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

📄 fastcompiler.java

📁 JPC: x86 PC Hardware Emulator. 牛津大学开发的一个纯JAVA的x86系统结构硬件模拟器。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*    JPC: A x86 PC Hardware Emulator for a pure Java Virtual Machine    Release Version 2.0    A project from the Physics Dept, The University of Oxford    Copyright (C) 2007 Isis Innovation Limited    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License version 2 as published by    the Free Software Foundation.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License along    with this program; if not, write to the Free Software Foundation, Inc.,    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.     Details (including contact information) can be found at:     www.physics.ox.ac.uk/jpc*/package org.jpc.emulator.memory.codeblock.fastcompiler;

import java.io.*;
import java.util.*;

import org.jpc.emulator.processor.ProcessorException;
import org.jpc.emulator.memory.codeblock.*;
import org.jpc.classfile.*;

import org.jpc.emulator.memory.codeblock.fastcompiler.real.*;
import org.jpc.emulator.memory.codeblock.fastcompiler.prot.*;

public class FASTCompiler implements CodeBlockCompiler
{
    public static final int PROCESSOR_ELEMENT_EAX = 0;
    public static final int PROCESSOR_ELEMENT_ECX = 1;
    public static final int PROCESSOR_ELEMENT_EDX = 2;
    public static final int PROCESSOR_ELEMENT_EBX = 3;
    public static final int PROCESSOR_ELEMENT_ESP = 4;
    public static final int PROCESSOR_ELEMENT_EBP = 5;
    public static final int PROCESSOR_ELEMENT_ESI = 6;
    public static final int PROCESSOR_ELEMENT_EDI = 7;

    public static final int PROCESSOR_ELEMENT_EIP = 8;

    public static final int PROCESSOR_ELEMENT_CFLAG = 9;
    public static final int PROCESSOR_ELEMENT_PFLAG = 10;
    public static final int PROCESSOR_ELEMENT_AFLAG = 11;
    public static final int PROCESSOR_ELEMENT_ZFLAG = 12;
    public static final int PROCESSOR_ELEMENT_SFLAG = 13;
    public static final int PROCESSOR_ELEMENT_TFLAG = 14;
    public static final int PROCESSOR_ELEMENT_IFLAG = 15;
    public static final int PROCESSOR_ELEMENT_DFLAG = 16;
    public static final int PROCESSOR_ELEMENT_OFLAG = 17;
    public static final int PROCESSOR_ELEMENT_IOPL = 18;
    public static final int PROCESSOR_ELEMENT_NTFLAG = 19;
    public static final int PROCESSOR_ELEMENT_RFLAG = 20;
    public static final int PROCESSOR_ELEMENT_VMFLAG = 21;
    public static final int PROCESSOR_ELEMENT_ACFLAG = 22;
    public static final int PROCESSOR_ELEMENT_VIFLAG = 23;
    public static final int PROCESSOR_ELEMENT_VIPFLAG = 24;
    public static final int PROCESSOR_ELEMENT_IDFLAG = 25;

    public static final int PROCESSOR_ELEMENT_ES = 26;
    public static final int PROCESSOR_ELEMENT_CS = 27;
    public static final int PROCESSOR_ELEMENT_SS = 28;
    public static final int PROCESSOR_ELEMENT_DS = 29;
    public static final int PROCESSOR_ELEMENT_FS = 30;
    public static final int PROCESSOR_ELEMENT_GS = 31;

    public static final int PROCESSOR_ELEMENT_IDTR = 32;
    public static final int PROCESSOR_ELEMENT_GDTR = 33;
    public static final int PROCESSOR_ELEMENT_LDTR = 34;
    public static final int PROCESSOR_ELEMENT_TSS = 35;

    public static final int PROCESSOR_ELEMENT_CPL = 36;

    public static final int PROCESSOR_ELEMENT_IOPORTS = 37;

    public static final int PROCESSOR_ELEMENT_ADDR0 = 38;

    public static final int PROCESSOR_ELEMENT_COUNT = 39;

    public static final int PROCESSOR_ELEMENT_REG0 = 39;
    public static final int PROCESSOR_ELEMENT_REG1 = 40;
    public static final int PROCESSOR_ELEMENT_REG2 = 41;

    public static final int PROCESSOR_ELEMENT_SEG0 = 42;

    public static final int POPABLE_ELEMENT_COUNT = 43;

    public static final int PROCESSOR_ELEMENT_MEMORYWRITE = 43;
    public static final int PROCESSOR_ELEMENT_IOPORTWRITE = 44;
    public static final int PROCESSOR_ELEMENT_EXECUTECOUNT = 45;

    public static final int ELEMENT_COUNT = 46;

    public static final int VARIABLE_EXECUTE_COUNT_INDEX = 10;
    public static final int VARIABLE_OFFSET = 11;

    private static int classIndex = 0;

    public ProtectedModeCodeBlock getProtectedModeCodeBlock(InstructionSource source)
    {
        MicrocodeNode[] microcodes = MicrocodeNode.getMicrocodes(source);
	ClassFile newClass = null;

        try {
            newClass = ClassFileBuilder.createNewProtectedModeSkeletonClass();
            MicrocodeNode last = microcodes[microcodes.length-1];

            newClass.setClassName("org.jpc.dynamic.FAST_PM_LEN" + last.getX86Index() + "_NUM"+(classIndex++));
	    
            int x86CountIndex = newClass.addToConstantPool(new Integer(last.getX86Index()));
            int x86LengthIndex = newClass.addToConstantPool(new Integer(last.getX86Position()));
            
            compileX86CountMethod(newClass, x86CountIndex);
            compileX86LengthMethod(newClass, x86LengthIndex);
            
            compileProtectedModeExecuteMethod(microcodes, newClass, x86CountIndex);

	    return (ProtectedModeCodeBlock) ClassFileBuilder.instantiateClass(newClass);
        } catch (Error e) {
	    //dumpClass(newClass);
            throw new IllegalStateException("Failed to compile Protected Mode FAST block : " + e, e);
        } catch (NullPointerException e) {
            throw new IllegalStateException("Failed to compile Protected Mode FAST block : " + e, e);
        } catch (IOException e) {
            throw new IllegalStateException("Failed to compile Protected Mode FAST block : " + e, e);
	}
    }
    
    public Virtual8086ModeCodeBlock getVirtual8086ModeCodeBlock(InstructionSource source)
    {
	throw new IllegalStateException("Cannot compile Virtual8086 Mode FAST blocks");
    }
    
    public RealModeCodeBlock getRealModeCodeBlock(InstructionSource source)
    {
        MicrocodeNode[] microcodes = MicrocodeNode.getMicrocodes(source);
	ClassFile newClass = null;

        try {
            newClass = ClassFileBuilder.createNewRealModeSkeletonClass();
            MicrocodeNode last = microcodes[microcodes.length-1];

            newClass.setClassName("org.jpc.dynamic.FAST_RM_LEN" + last.getX86Index() + "_NUM"+(classIndex++));
	    
            int x86CountIndex = newClass.addToConstantPool(new Integer(last.getX86Index()));
            int x86LengthIndex = newClass.addToConstantPool(new Integer(last.getX86Position()));
            
            compileX86CountMethod(newClass, x86CountIndex);
            compileX86LengthMethod(newClass, x86LengthIndex);
            
            compileRealModeExecuteMethod(microcodes, newClass, x86CountIndex);
            
	    return (RealModeCodeBlock) ClassFileBuilder.instantiateClass(newClass);
        } catch (Error e) {
	    //dumpClass(newClass);
            throw new IllegalStateException("Failed to compile Real Mode FAST block : " + e, e);
        } catch (NullPointerException e) {
            throw new IllegalStateException("Failed to compile Real Mode FAST block : " + e, e);
        } catch (IOException e) {
            throw new IllegalStateException("Failed to compile Real Mode FAST block : " + e, e);
	}
    }

    private static void compileProtectedModeExecuteMethod(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 ProtectedModeRPNNode(i, null));
        
	int lastX86Position = 0;

        for (int i=0; i<microcodes.length; i++) {
            MicrocodeNode node = microcodes[i];
            int uCode = node.getMicrocode();
            
            Object[] codes = ProtectedModeBytecodeFragments.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;
                
                ProtectedModeRPNNode rpn = new ProtectedModeRPNNode(j, node);
                if (rpn.hasExternalEffect())
                    externalEffects.add(rpn);

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

                targets.add(rpn);
                
                int[] argIds = ProtectedModeBytecodeFragments.getOperands(j, uCode);
                if (argIds == null)
                    System.out.println("NULL IDS FOR: "+j+"  "+uCode);
                
                for (int k=0; k<argIds.length; k++) {
                    ProtectedModeRPNNode arg = (ProtectedModeRPNNode) currentElements.get(new Integer(argIds[k]));
                    rpn.linkTo(arg);
                }
            }
            
            for (int j=0; j<targets.size(); j++) {
                ProtectedModeRPNNode rpn = (ProtectedModeRPNNode) 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 = ((ProtectedModeRPNNode)externalEffects.get(i)).markSubtrees(localVariableIndex);
        
        int affectedCount = 0;
	for (Iterator itt = currentElements.values().iterator(); itt.hasNext();) {
            ProtectedModeRPNNode rpn = (ProtectedModeRPNNode) itt.next();

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

⌨️ 快捷键说明

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