Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JVM第7次作业 #35

Merged
merged 3 commits into from
May 31, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.coderising.jvm.attr;

public class ConstantValue extends AttributeInfo {

private int constValueIndex;

public ConstantValue(int attrNameIndex, int attrLen) {
super(attrNameIndex, attrLen);
}


public int getConstValueIndex() {
return constValueIndex;
}
public void setConstValueIndex(int constValueIndex) {
this.constValueIndex = constValueIndex;
}



}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ public abstract class ByteCodeCommand {
static{
codeMap.put("01", "aconst_null");

codeMap.put("A2", "if_icmp_ge");
codeMap.put("A4", "if_icmple");
codeMap.put("A7", "goto");

codeMap.put("BB", "new");
codeMap.put("37", "lstore");
codeMap.put("B7", "invokespecial");
Expand Down Expand Up @@ -149,4 +153,4 @@ public String getReadableCodeText(){
}

public abstract void execute(StackFrame frame,ExecutionResult result);
}
}
136 changes: 60 additions & 76 deletions group06/1378560653/mini-jvm/com/coderising/jvm/cmd/CommandParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,123 +7,107 @@

public class CommandParser {

public static final String aconst_null = "01";
public static final String new_object = "BB";
public static final String lstore = "37";
public static final String invokespecial = "B7";
public static final String invokevirtual = "B6";
public static final String getfield = "B4";
public static final String putfield = "B5";
public static final String getstatic = "B2";
public static final String ldc = "12";
public static final String dup = "59";
public static final String bipush = "10";
public static final String aload_0 = "2A";
public static final String aload_1 = "2B";
public static final String aload_2 = "2C";
public static final String iload = "15";
public static final String iload_1 = "1B";
public static final String iload_2 = "1C";
public static final String iload_3 = "1D";
public static final String fload_3 = "25";

public static final String voidreturn = "B1";
public static final String ireturn = "AC";
public static final String freturn = "AE";

public static final String astore_1 = "4C";
public static final String if_icmp_ge = "A2";
public static final String if_icmple = "A4";
public static final String goto_no_condition = "A7";
public static final String iconst_0 = "03";
public static final String iconst_1 = "04";
public static final String istore_1 = "3C";
public static final String istore_2 = "3D";
public static final String iadd = "60";
public static final String iinc = "84";


public static ByteCodeCommand[] parse(ClassFile clzFile, String codes) {
if((codes == null) || (codes.length() == 0) || (codes.length() % 2 )!=0 ) {
throw new RuntimeException("the original code is not correct.");
} //为什么必须是偶数呢?


if ((codes == null) || (codes.length() == 0) || (codes.length() % 2) != 0) {
throw new RuntimeException("the orignal code is not correct");

}

codes = codes.toUpperCase();
CommandIterator iter = new CommandIterator(codes); //iter是codes的一个迭代器

CommandIterator iter = new CommandIterator(codes);
List<ByteCodeCommand> cmds = new ArrayList<ByteCodeCommand>();
while(iter.hasNext()){

while (iter.hasNext()) {
String opCode = iter.next2CharAsString();
if(opCode.equals(new_object)){

if (ByteCodeCommand.new_object.equals(opCode)) {
NewObjectCmd cmd = new NewObjectCmd(clzFile, opCode);

cmd.setOprand1(iter.next2CharAsInt());
cmd.setOprand2(iter.next2CharAsInt());

cmds.add(cmd);
} else if (opCode.equals(invokespecial)){
} else if (ByteCodeCommand.invokespecial.equals(opCode)) {
InvokeSpecialCmd cmd = new InvokeSpecialCmd(clzFile, opCode);

cmd.setOprand1(iter.next2CharAsInt());
cmd.setOprand2(iter.next2CharAsInt());

// System.out.println( cmd.toString(clzFile.getConstPool()));
cmds.add(cmd);
} else if (opCode.equals(invokevirtual)){
} else if (ByteCodeCommand.invokevirtual.equals(opCode)) {
InvokeVirtualCmd cmd = new InvokeVirtualCmd(clzFile, opCode);

cmd.setOprand1(iter.next2CharAsInt());
cmd.setOprand2(iter.next2CharAsInt());

cmds.add(cmd);
} else if (opCode.equals(getfield)){
} else if (ByteCodeCommand.getfield.equals(opCode)) {
GetFieldCmd cmd = new GetFieldCmd(clzFile, opCode);

cmd.setOprand1(iter.next2CharAsInt());
cmd.setOprand2(iter.next2CharAsInt());

cmds.add(cmd);
} else if (opCode.equals(getstatic)){
} else if (ByteCodeCommand.getstatic.equals(opCode)) {
GetStaticFieldCmd cmd = new GetStaticFieldCmd(clzFile, opCode);

cmd.setOprand1(iter.next2CharAsInt());
cmd.setOprand2(iter.next2CharAsInt());

cmds.add(cmd);
} else if (opCode.equals(putfield)){
} else if (ByteCodeCommand.putfield.equals(opCode)) {
PutFieldCmd cmd = new PutFieldCmd(clzFile, opCode);

cmd.setOprand1(iter.next2CharAsInt());
cmd.setOprand2(iter.next2CharAsInt());

cmds.add(cmd);
} else if (opCode.equals(ldc)){
} else if (ByteCodeCommand.ldc.equals(opCode)) {
LdcCmd cmd = new LdcCmd(clzFile, opCode);

cmd.setOperand(iter.next2CharAsInt());

cmds.add(cmd);
} else if (opCode.equals(bipush)){
} else if (ByteCodeCommand.bipush.equals(opCode)) {
BiPushCmd cmd = new BiPushCmd(clzFile, opCode);

cmd.setOperand(iter.next2CharAsInt());

cmds.add(cmd);
} else if (dup.equals(opCode) || aload_0.equals(opCode) || aload_1.equals(opCode) || aload_2.equals(opCode)
|| iload_1.equals(opCode) || iload_2.equals(opCode) || iload_3.equals(opCode)
|| fload_3.equals(opCode) || voidreturn.equals(opCode) || astore_1.equals(opCode)) {

}else if(ByteCodeCommand.if_icmp_ge.equals(opCode)
|| ByteCodeCommand.if_icmple.equals(opCode)
|| ByteCodeCommand.goto_no_condition.equals(opCode)){
ComparisonCmd cmd = new ComparisonCmd(clzFile,opCode);
cmd.setOprand1(iter.next2CharAsInt());
cmd.setOprand2(iter.next2CharAsInt());
cmds.add(cmd);
} else if(ByteCodeCommand.iinc.equals(opCode)){
IncrementCmd cmd = new IncrementCmd(clzFile,opCode);
cmd.setOprand1(iter.next2CharAsInt());
cmd.setOprand2(iter.next2CharAsInt());
cmds.add(cmd);
}
else if (ByteCodeCommand.dup.equals(opCode)
|| ByteCodeCommand.aload_0.equals(opCode)
|| ByteCodeCommand.aload_1.equals(opCode)
|| ByteCodeCommand.aload_2.equals(opCode)
|| ByteCodeCommand.iload_1.equals(opCode)
|| ByteCodeCommand.iload_2.equals(opCode)
|| ByteCodeCommand.iload_3.equals(opCode)
|| ByteCodeCommand.fload_3.equals(opCode)
|| ByteCodeCommand.iconst_0.equals(opCode)
|| ByteCodeCommand.iconst_1.equals(opCode)
|| ByteCodeCommand.istore_1.equals(opCode)
|| ByteCodeCommand.istore_2.equals(opCode)
|| ByteCodeCommand.voidreturn.equals(opCode)
|| ByteCodeCommand.iadd.equals(opCode)
|| ByteCodeCommand.astore_1.equals(opCode)
|| ByteCodeCommand.ireturn.equals(opCode)) {

NoOperandCmd cmd = new NoOperandCmd(clzFile, opCode);
cmds.add(cmd);
} else {
throw new RuntimeException("sorry, the java instruction "+opCode+"has not been implemented.");
throw new RuntimeException("Sorry, the java instruction " + opCode + " has not been implemented");
}

}

calcuateOffset(cmds);

ByteCodeCommand[] result = new ByteCodeCommand[cmds.size()];
cmds.toArray(result); //list.toArray(array);
cmds.toArray(result);
return result;
}

Expand Down Expand Up @@ -161,4 +145,4 @@ public int next2CharAsInt() {
}

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package com.coderising.jvm.cmd;

import com.coderising.jvm.clz.ClassFile;
import com.coderising.jvm.engine.ExecutionResult;
import com.coderising.jvm.engine.JavaObject;
import com.coderising.jvm.engine.StackFrame;

public class ComparisonCmd extends TwoOperandCmd {

protected ComparisonCmd(ClassFile clzFile, String opCode) {
super(clzFile, opCode);

}


@Override
public void execute(StackFrame frame,ExecutionResult result) {

if(ByteCodeCommand.if_icmp_ge.equals(this.getOpCode())){
//注意次序
JavaObject jo2 = frame.getOprandStack().pop();
JavaObject jo1 = frame.getOprandStack().pop();

if(jo1.getIntValue() >= jo2.getIntValue()){

this.setJumpResult(result);

}

} else if(ByteCodeCommand.if_icmple.equals(this.getOpCode())){
//注意次序
JavaObject jo2 = frame.getOprandStack().pop();
JavaObject jo1 = frame.getOprandStack().pop();

if(jo1.getIntValue() <= jo2.getIntValue()){
this.setJumpResult(result);
}

} else if(ByteCodeCommand.goto_no_condition.equals(this.getOpCode())){
this.setJumpResult(result);

} else{
throw new RuntimeException(this.getOpCode() + "has not been implemented");
}




}

private int getOffsetFromStartCmd(){
//If the comparison succeeds, the unsigned branchbyte1 and branchbyte2
//are used to construct a signed 16-bit offset, where the offset is calculated
//to be (branchbyte1 << 8) | branchbyte2. Execution then proceeds at that
//offset from the address of the opcode of this if_icmp<cond> instruction


int index1 = this.getOprand1();
int index2 = this.getOprand2();
short offsetFromCurrent = (short)(index1 << 8 | index2);
return this.getOffset() + offsetFromCurrent ;
}
private void setJumpResult(ExecutionResult result){

int offsetFromStartCmd = this.getOffsetFromStartCmd();

result.setNextAction(ExecutionResult.JUMP);
result.setNextCmdOffset(offsetFromStartCmd);
}

@Override
public String toString() {
int index = this.getIndex();
String text = this.getReadableCodeText();
return this.getOffset()+":"+ this.getOpCode() + " "+text + " " + this.getOffsetFromStartCmd();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.coderising.jvm.cmd;

import com.coderising.jvm.clz.ClassFile;
import com.coderising.jvm.engine.ExecutionResult;
import com.coderising.jvm.engine.Heap;
import com.coderising.jvm.engine.JavaObject;
import com.coderising.jvm.engine.StackFrame;

public class IncrementCmd extends TwoOperandCmd {

public IncrementCmd(ClassFile clzFile, String opCode) {
super(clzFile, opCode);

}

@Override
public String toString() {

return this.getOffset()+":"+this.getOpCode()+ " " +this.getReadableCodeText();
}

@Override
public void execute(StackFrame frame, ExecutionResult result) {

int index = this.getOprand1();

int constValue = this.getOprand2();

int currentValue = frame.getLocalVariableValue(index).getIntValue();

JavaObject jo = Heap.getInstance().newInt(constValue+currentValue);

frame.setLocalVariableValue(index, jo);


}

}
Loading