irgenerator.java
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 1,392 行 · 第 1/3 页
JAVA
1,392 行
/*
* $Id: IRGenerator.java,v 1.18 2004/02/24 08:05:06 epr Exp $
*
* mailto:madhu@madhu.com
*/
package org.jnode.vm.compiler.ir;
import java.util.Iterator;
import org.jnode.util.BootableArrayList;
import org.jnode.vm.bytecode.BytecodeParser;
import org.jnode.vm.bytecode.BytecodeVisitor;
import org.jnode.vm.classmgr.VmByteCode;
import org.jnode.vm.classmgr.VmConstClass;
import org.jnode.vm.classmgr.VmConstFieldRef;
import org.jnode.vm.classmgr.VmConstIMethodRef;
import org.jnode.vm.classmgr.VmConstMethodRef;
import org.jnode.vm.classmgr.VmConstString;
import org.jnode.vm.classmgr.VmMethod;
import org.jnode.vm.compiler.ir.quad.BinaryQuad;
import org.jnode.vm.compiler.ir.quad.ConditionalBranchQuad;
import org.jnode.vm.compiler.ir.quad.ConstantRefAssignQuad;
import org.jnode.vm.compiler.ir.quad.Quad;
import org.jnode.vm.compiler.ir.quad.UnaryQuad;
import org.jnode.vm.compiler.ir.quad.UnconditionalBranchQuad;
import org.jnode.vm.compiler.ir.quad.VarReturnQuad;
import org.jnode.vm.compiler.ir.quad.VariableRefAssignQuad;
import org.jnode.vm.compiler.ir.quad.VoidReturnQuad;
/**
* Intermediate Representation Generator.
* Visits bytecodes of a given method and translates them into a
* list of Quads.
*/
public class IRGenerator extends BytecodeVisitor {
private final static Constant NULL_CONSTANT = Constant.getInstance(null);
private int nArgs;
private int nLocals;
private int maxStack;
private int stackOffset;
private Variable[] variables;
private int address;
private BootableArrayList quadList;
private Iterator basicBlockIterator;
private IRBasicBlock currentBlock;
/**
*
*/
public IRGenerator(IRControlFlowGraph cfg) {
basicBlockIterator = cfg.basicBlockIterator();
currentBlock = (IRBasicBlock) basicBlockIterator.next();
}
public BootableArrayList getQuadList() {
return quadList;
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#setParser(org.jnode.vm.bytecode.BytecodeParser)
*/
public void setParser(BytecodeParser parser) {
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#startMethod(org.jnode.vm.classmgr.VmMethod)
*/
public void startMethod(VmMethod method) {
VmByteCode code = method.getBytecode();
nArgs = method.getArgSlotCount();
nLocals = code.getNoLocals();
maxStack = code.getMaxStack();
stackOffset = nLocals;
variables = new Variable[nLocals + maxStack];
int index = 0;
for (int i=0; i<nArgs; i+=1) {
variables[index] = new MethodArgument(Operand.UNKNOWN, index);
index += 1;
}
for (int i=nArgs; i<nLocals; i+=1) {
variables[index] = new LocalVariable(Operand.UNKNOWN, index);
index += 1;
}
for (int i=0; i<maxStack; i+=1) {
variables[index] = new StackVariable(Operand.UNKNOWN, index);
index += 1;
}
quadList = new BootableArrayList(code.getLength() >> 1);
currentBlock.setVariables(variables);
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#endMethod()
*/
public void endMethod() {
// patch last block
currentBlock.resolvePhiReferences();
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#startInstruction(int)
*/
public void startInstruction(int address) {
this.address = address;
if (address >= currentBlock.getEndPC()) {
currentBlock.resolvePhiReferences();
currentBlock = (IRBasicBlock) basicBlockIterator.next();
Iterator pi = currentBlock.getPredecessors().iterator();
if (!pi.hasNext()) {
// this must be the first block in the method
return;
}
while (pi.hasNext()) {
IRBasicBlock irb = (IRBasicBlock) pi.next();
if (irb.getEndPC() <= address) {
Variable[] prevVars = irb.getVariables();
int n = prevVars.length;
variables = new Variable[n];
for (int i=0; i<n; i+=1) {
variables[i] = prevVars[i];
}
currentBlock.setVariables(variables);
return;
}
}
throw new AssertionError("can't find a preceding basic block");
}
if (address < currentBlock.getStartPC() || address >= currentBlock.getEndPC()) {
throw new AssertionError("instruction not in basic block!");
}
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#endInstruction()
*/
public void endInstruction() {
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_nop()
*/
public void visit_nop() {
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_aconst_null()
*/
public void visit_aconst_null() {
quadList.add(new ConstantRefAssignQuad(address, currentBlock, stackOffset,
NULL_CONSTANT));
stackOffset += 1;
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_iconst(int)
*/
public void visit_iconst(int value) {
Quad quad = new ConstantRefAssignQuad(address, currentBlock, stackOffset,
Constant.getInstance(value));
quadList.add(quad);
stackOffset += 1;
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_lconst(long)
*/
public void visit_lconst(long value) {
quadList.add(new ConstantRefAssignQuad(address, currentBlock, stackOffset,
Constant.getInstance(value)));
stackOffset += 2;
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_fconst(float)
*/
public void visit_fconst(float value) {
quadList.add(new ConstantRefAssignQuad(address, currentBlock, stackOffset,
Constant.getInstance(value)));
stackOffset += 1;
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_dconst(double)
*/
public void visit_dconst(double value) {
quadList.add(new ConstantRefAssignQuad(address, currentBlock, stackOffset,
Constant.getInstance(value)));
stackOffset += 2;
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_ldc(VmConstString)
*/
public void visit_ldc(VmConstString value) {
throw new IllegalArgumentException("byte code not yet supported");
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_iload(int)
*/
public void visit_iload(int index) {
variables[index].setType(Operand.INT);
variables[stackOffset].setType(Operand.INT);
VariableRefAssignQuad assignQuad = new VariableRefAssignQuad(address, currentBlock,
stackOffset, index);
quadList.add(assignQuad);
stackOffset += 1;
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_lload(int)
*/
public void visit_lload(int index) {
variables[index].setType(Operand.LONG);
variables[stackOffset].setType(Operand.LONG);
quadList.add(new VariableRefAssignQuad(address, currentBlock,
stackOffset, index));
stackOffset += 2;
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_fload(int)
*/
public void visit_fload(int index) {
variables[index].setType(Operand.FLOAT);
variables[stackOffset].setType(Operand.FLOAT);
quadList.add(new VariableRefAssignQuad(address, currentBlock,
stackOffset, index));
stackOffset += 1;
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_dload(int)
*/
public void visit_dload(int index) {
variables[index].setType(Operand.DOUBLE);
variables[stackOffset].setType(Operand.DOUBLE);
quadList.add(new VariableRefAssignQuad(address, currentBlock,
stackOffset, index));
stackOffset += 2;
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_aload(int)
*/
public void visit_aload(int index) {
variables[index].setType(Operand.REFERENCE);
variables[stackOffset].setType(Operand.REFERENCE);
quadList.add(new VariableRefAssignQuad(address, currentBlock, stackOffset, index));
stackOffset += 1;
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_iaload()
*/
public void visit_iaload() {
throw new IllegalArgumentException("byte code not yet supported");
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_laload()
*/
public void visit_laload() {
throw new IllegalArgumentException("byte code not yet supported");
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_faload()
*/
public void visit_faload() {
throw new IllegalArgumentException("byte code not yet supported");
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_daload()
*/
public void visit_daload() {
throw new IllegalArgumentException("byte code not yet supported");
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_aaload()
*/
public void visit_aaload() {
throw new IllegalArgumentException("byte code not yet supported");
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_baload()
*/
public void visit_baload() {
throw new IllegalArgumentException("byte code not yet supported");
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_caload()
*/
public void visit_caload() {
throw new IllegalArgumentException("byte code not yet supported");
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_saload()
*/
public void visit_saload() {
throw new IllegalArgumentException("byte code not yet supported");
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_istore(int)
*/
public void visit_istore(int index) {
stackOffset -= 1;
variables[index].setType(Operand.INT);
variables[stackOffset].setType(Operand.INT);
VariableRefAssignQuad assignQuad = new VariableRefAssignQuad(address, currentBlock, index, stackOffset);
quadList.add(assignQuad);
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_lstore(int)
*/
public void visit_lstore(int index) {
stackOffset -= 2;
variables[index].setType(Operand.LONG);
variables[stackOffset].setType(Operand.LONG);
quadList.add(new VariableRefAssignQuad(address, currentBlock, index, stackOffset));
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_fstore(int)
*/
public void visit_fstore(int index) {
stackOffset -= 1;
variables[index].setType(Operand.FLOAT);
variables[stackOffset].setType(Operand.FLOAT);
quadList.add(new VariableRefAssignQuad(address, currentBlock, index, stackOffset));
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_dstore(int)
*/
public void visit_dstore(int index) {
stackOffset -= 2;
variables[index].setType(Operand.DOUBLE);
variables[stackOffset].setType(Operand.DOUBLE);
quadList.add(new VariableRefAssignQuad(address, currentBlock, index, stackOffset));
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_astore(int)
*/
public void visit_astore(int index) {
stackOffset -= 1;
variables[index].setType(Operand.REFERENCE);
variables[stackOffset].setType(Operand.REFERENCE);
quadList.add(new VariableRefAssignQuad(address, currentBlock, index, stackOffset));
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_iastore()
*/
public void visit_iastore() {
throw new IllegalArgumentException("byte code not yet supported");
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_lastore()
*/
public void visit_lastore() {
throw new IllegalArgumentException("byte code not yet supported");
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_fastore()
*/
public void visit_fastore() {
throw new IllegalArgumentException("byte code not yet supported");
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_dastore()
*/
public void visit_dastore() {
throw new IllegalArgumentException("byte code not yet supported");
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_aastore()
*/
public void visit_aastore() {
throw new IllegalArgumentException("byte code not yet supported");
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_bastore()
*/
public void visit_bastore() {
throw new IllegalArgumentException("byte code not yet supported");
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_castore()
*/
public void visit_castore() {
throw new IllegalArgumentException("byte code not yet supported");
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_sastore()
*/
public void visit_sastore() {
throw new IllegalArgumentException("byte code not yet supported");
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_pop()
*/
public void visit_pop() {
throw new IllegalArgumentException("byte code not yet supported");
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_pop2()
*/
public void visit_pop2() {
throw new IllegalArgumentException("byte code not yet supported");
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_dup()
*/
public void visit_dup() {
throw new IllegalArgumentException("byte code not yet supported");
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_dup_x1()
*/
public void visit_dup_x1() {
throw new IllegalArgumentException("byte code not yet supported");
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_dup_x2()
*/
public void visit_dup_x2() {
throw new IllegalArgumentException("byte code not yet supported");
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_dup2()
*/
public void visit_dup2() {
throw new IllegalArgumentException("byte code not yet supported");
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_dup2_x1()
*/
public void visit_dup2_x1() {
throw new IllegalArgumentException("byte code not yet supported");
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?