📄 opcodestack.java
字号:
} break; case DNEG: it = pop(); if (it.getConstant() != null) { push(new Item("D", new Double(-((Double)it.getConstant()).doubleValue()))); } else { push(new Item("D")); } break; case LADD: case LSUB: case LMUL: case LDIV: case LAND: case LOR: case LXOR: case LSHL: case LSHR: case LREM: case LUSHR: it = pop(); it2 = pop(); pushByLongMath(seen, it, it2); break; case LCMP: it = pop(); it2 = pop(); if ((it.getConstant() != null) && it2.getConstant() != null) { long l = ((Long)it.getConstant()).longValue(); long l2 = ((Long)it.getConstant()).longValue(); if (l2 < l) push(new Item("I", new Integer(-1))); else if (l2 > l) push(new Item("I", new Integer(1))); else push(new Item("I", new Integer(0))); } else { push(new Item("I")); } break; case FCMPG: case FCMPL: it = pop(); it2 = pop(); if ((it.getConstant() != null) && it2.getConstant() != null) { float f = ((Float)it.getConstant()).floatValue(); float f2 = ((Float)it.getConstant()).floatValue(); if (f2 < f) push(new Item("I", new Integer(-1))); else if (f2 > f) push(new Item("I", new Integer(1))); else push(new Item("I", new Integer(0))); } else { push(new Item("I")); } break; case DCMPG: case DCMPL: it = pop(); it2 = pop(); if ((it.getConstant() != null) && it2.getConstant() != null) { double d = ((Double)it.getConstant()).doubleValue(); double d2 = ((Double)it.getConstant()).doubleValue(); if (d2 < d) push(new Item("I", new Integer(-1))); else if (d2 > d) push(new Item("I", new Integer(1))); else push(new Item("I", new Integer(0))); } else { push(new Item("I")); } break; case FADD: case FSUB: case FMUL: case FDIV: it = pop(); it2 = pop(); pushByFloatMath(seen, it, it2); break; case DADD: case DSUB: case DMUL: case DDIV: case DREM: it = pop(); it2 = pop(); pushByDoubleMath(seen, it, it2); break; case I2B: it = pop(); if (it.getConstant() != null) { push(new Item("I", new Integer((int)((byte)((Integer)it.getConstant()).intValue())))); } else { push(new Item("I")); } break; case I2C: it = pop(); if (it.getConstant() != null) { push(new Item("I", new Integer((int)((char)((Integer)it.getConstant()).intValue())))); } else { push(new Item("I")); } break; case I2D: it = pop(); if (it.getConstant() != null) { push(new Item("D", new Double((double)((Integer)it.getConstant()).intValue()))); } else { push(new Item("D")); } break; case I2F: it = pop(); if (it.getConstant() != null) { push(new Item("F", new Float((float)((Integer)it.getConstant()).intValue()))); } else { push(new Item("F")); } break; case I2L: it = pop(); if (it.getConstant() != null) { push(new Item("J", new Long((long)((Integer)it.getConstant()).intValue()))); } else { push(new Item("J")); } break; case I2S: it = pop(); if (it.getConstant() != null) { push(new Item("I", new Integer((int)((short)((Integer)it.getConstant()).intValue())))); } else { push(new Item("I")); } break; case D2I: it = pop(); if (it.getConstant() != null) { push(new Item("I", new Integer((int)((Integer)it.getConstant()).intValue()))); } else { push(new Item("I")); } break; case D2F: it = pop(); if (it.getConstant() != null) { push(new Item("F", new Float((float)((Double)it.getConstant()).doubleValue()))); } else { push(new Item("F")); } break; case D2L: it = pop(); if (it.getConstant() != null) { push(new Item("J", new Long((long)((Double)it.getConstant()).doubleValue()))); } else { push(new Item("J")); } break; case L2I: it = pop(); if (it.getConstant() != null) { push(new Item("I", new Integer((int)((Long)it.getConstant()).longValue()))); } else { push(new Item("I")); } break; case L2D: it = pop(); if (it.getConstant() != null) { push(new Item("D", new Double((double)((Long)it.getConstant()).longValue()))); } else { push(new Item("D")); } break; case L2F: it = pop(); if (it.getConstant() != null) { push(new Item("F", new Float((float)((Long)it.getConstant()).longValue()))); } else { push(new Item("F")); } break; case F2I: it = pop(); if (it.getConstant() != null) { push(new Item("I", new Integer((int)((Float)it.getConstant()).floatValue()))); } else { push(new Item("I")); } break; case F2D: it = pop(); if (it.getConstant() != null) { push(new Item("D", new Double((double)((Float)it.getConstant()).floatValue()))); } else { push(new Item("D")); } break; case NEW: pushBySignature(dbc.getClassConstantOperand()); break; case NEWARRAY: pop(); signature = BasicType.getType((byte)dbc.getIntConstant()).getSignature(); pushBySignature(signature); break; // According to the VM Spec 4.4.1, anewarray and multianewarray // can refer to normal class/interface types (encoded in // "internal form"), or array classes (encoded as signatures // beginning with "["). case ANEWARRAY: pop(); signature = dbc.getClassConstantOperand(); if (!signature.startsWith("[")) { signature = "L" + signature + ";"; } pushBySignature(signature); break; case MULTIANEWARRAY: int dims = dbc.getIntConstant(); while ((dims--) > 0) { pop(); } signature = dbc.getClassConstantOperand(); if (!signature.startsWith("[")) { signature = "L" + signature + ";"; } pushBySignature(signature); break; case AALOAD: pop(); it = pop(); pushBySignature(it.getElementSignature()); break; case JSR: push(new Item("")); //? break; case INVOKEINTERFACE: case INVOKESPECIAL: case INVOKESTATIC: case INVOKEVIRTUAL: pushByInvoke(dbc, seen != INVOKESTATIC); break; default: throw new UnsupportedOperationException("OpCode not supported yet" ); } }/* // FIXME: This class currently relies on catching runtime exceptions. // This should be fixed so they don't occur. catch (RuntimeException e) { throw e; }*/ catch (Exception e) { //If an error occurs, we clear the stack and locals. one of two things will occur. //Either the client will expect more stack items than really exist, and so they're condition check will fail, //or the stack will resync with the code. But hopefully not false positives stack.clear(); lvValues.clear(); } finally { if (DEBUG) System.out.println(OPCODE_NAMES[seen] + " stack depth: " + getStackDepth()); } } public int getStackDepth() { return stack.size(); } public Item getStackItem(int stackOffset) { int tos = stack.size() - 1; int pos = tos - stackOffset; return stack.get(pos); } private Item pop() { return stack.remove(stack.size()-1); } private void pop(int count) { while ((count--) > 0) pop(); } private void push(Item i) { stack.add(i); } private void pushByConstant(DismantleBytecode dbc, Constant c) { if (c instanceof ConstantInteger) push(new Item("I", new Integer(((ConstantInteger) c).getBytes()))); else if (c instanceof ConstantString) { int s = ((ConstantString) c).getStringIndex(); push(new Item("Ljava/lang/String;", getStringFromIndex(dbc, s))); } else if (c instanceof ConstantFloat) push(new Item("F", new Float(((ConstantInteger) c).getBytes()))); else if (c instanceof ConstantDouble) push(new Item("D", new Double(((ConstantDouble) c).getBytes()))); else if (c instanceof ConstantLong) push(new Item("J", new Long(((ConstantLong) c).getBytes()))); else throw new UnsupportedOperationException("Constant type not expected" ); } private void pushByLocalObjectLoad(DismantleBytecode dbc, int register) { Method m = dbc.getMethod(); LocalVariableTable lvt = m.getLocalVariableTable(); if (lvt != null) { LocalVariable lv = LVTHelper.getLocalVariableAtPC(lvt, register, dbc.getPC()); if (lv != null) { String signature = lv.getSignature(); pushByLocalLoad(signature, register); return; } } pushBySignature(""); } private void pushByIntMath(int seen, Item it, Item it2) { if ((it.getConstant() != null) && it2.getConstant() != null) { if (seen == IADD) push(new Item("I", new Integer(((Integer)it2.getConstant()).intValue() + ((Integer)it.getConstant()).intValue()))); else if (seen == ISUB) push(new Item("I", new Integer(((Integer)it2.getConstant()).intValue() - ((Integer)it.getConstant()).intValue()))); else if (seen == IMUL) push(new Item("I", new Integer(((Integer)it2.getConstant()).intValue() * ((Integer)it.getConstant()).intValue()))); else if (seen == IDIV) push(new Item("I", new Integer(((Integer)it2.getConstant()).intValue() / ((Integer)it.getConstant()).intValue()))); else if (seen == IAND) push(new Item("I", new Integer(((Integer)it2.getConstant()).intValue() & ((Integer)it.getConstant()).intValue()))); else if (seen == IOR) push(new Item("I", new Integer(((Integer)it2.getConstant()).intValue() | ((Integer)it.getConstant()).intValue()))); else if (seen == IXOR) push(new Item("I", new Integer(((Integer)it2.getConstant()).intValue() ^ ((Integer)it.getConstant()).intValue()))); else if (seen == ISHL) push(new Item("I", new Integer(((Integer)it2.getConstant()).intValue() << ((Integer)it.getConstant()).intValue()))); else if (seen == ISHR) push(new Item("I", new Integer(((Integer)it2.getConstant()).intValue() >> ((Integer)it.getConstant()).intValue()))); else if (seen == IREM) push(new Item("I", new Integer(((Integer)it2.getConstant()).intValue() % ((Integer)it.getConstant()).intValue()))); else if (seen == IUSHR) push(new Item("I", new Integer(((Integer)it2.getConstant()).intValue() >>> ((Integer)it.getConstant()).intValue()))); } else { push(new Item("I")); } } private void pushByLongMath(int seen, Item it, Item it2) { if ((it.getConstant() != null) && it2.getConstant() != null) { if (seen == LADD) push(new Item("J", new Long(((Long)it2.getConstant()).longValue() + ((Long)it.getConstant()).longValue()))); else if (seen == LSUB) push(new Item("J", new Long(((Long)it2.getConstant()).longValue() - ((Long)it.getConstant()).longValue()))); else if (seen == LMUL) push(new Item("J", new Long(((Long)it2.getConstant()).longValue() * ((Long)it.getConstant()).longValue()))); else if (seen == LDIV) push(new Item("J", new Long(((Long)it2.getConstant()).longValue() / ((Long)it.getConstant()).longValue()))); else if (seen == LAND) push(new Item("J", new Long(((Long)it2.getConstant()).longValue() & ((Long)it.getConstant()).longValue()))); else if (seen == LOR) push(new Item("J", new Long(((Long)it2.getConstant()).longValue() | ((Long)it.getConstant()).longValue()))); else if (seen == LXOR) push(new Item("J", new Long(((Long)it2.getConstant()).longValue() ^ ((Long)it.getConstant()).longValue()))); else if (seen == LSHL) push(new Item("J", new Long(((Long)it2.getConstant()).longValue() << ((Long)it.getConstant()).longValue()))); else if (seen == LSHR) push(new Item("J", new Long(((Long)it2.getConstant()).longValue() >> ((Long)it.getConstant()).longValue()))); else if (seen == LREM) push(new Item("J", new Long(((Long)it2.getConstant()).longValue() % ((Long)it.getConstant()).longValue()))); else if (seen == LUSHR) push(new Item("J", new Long(((Long)it2.getConstant()).longValue() >>> ((Long)it.getConstant()).longValue()))); } else { push(new Item("J")); } } private void pushByFloatMath(int seen, Item it, Item it2) { if ((it.getConstant() != null) && it2.getConstant() != null) { if (seen == FADD) push(new Item("F", new Float(((Float)it2.getConstant()).floatValue() + ((Float)it.getConstant()).floatValue()))); else if (seen == FSUB) push(new Item("F", new Float(((Float)it2.getConstant()).floatValue() - ((Float)it.getConstant()).floatValue()))); else if (seen == FMUL) push(new Item("F", new Float(((Float)it2.getConstant()).floatValue() * ((Float)it.getConstant()).floatValue()))); else if (seen == FDIV) push(new Item("F", new Float(((Float)it2.getConstant()).floatValue() / ((Float)it.getConstant()).floatValue()))); } else { push(new Item("F")); } } private void pushByDoubleMath(int seen, Item it, Item it2) { if ((it.getConstant() != null) && it2.getConstant() != null) { if (seen == DADD) push(new Item("D", new Double(((Double)it2.getConstant()).doubleValue() + ((Double)it.getConstant()).doubleValue()))); else if (seen == DSUB) push(new Item("D", new Double(((Double)it2.getConstant()).doubleValue() - ((Double)it.getConstant()).doubleValue()))); else if (seen == DMUL) push(new Item("D", new Double(((Double)it2.getConstant()).doubleValue() * ((Double)it.getConstant()).doubleValue()))); else if (seen == DDIV) push(new Item("D", new Double(((Double)it2.getConstant()).doubleValue() / ((Double)it.getConstant()).doubleValue()))); else if (seen == DREM) push(new Item("D")); //? } else { push(new Item("D")); } } private void pushByInvoke(DismantleBytecode dbc, boolean popThis) { String signature = dbc.getSigConstantOperand(); Type[] argTypes = Type.getArgumentTypes(signature); pop(argTypes.length+(popThis ? 1 : 0)); pushBySignature(Type.getReturnType(signature).getSignature()); } private String getStringFromIndex(DismantleBytecode dbc, int i) { ConstantUtf8 name = (ConstantUtf8) dbc.getConstantPool().getConstant(i); return name.getBytes(); } private void pushBySignature(String s) { if ("V".equals(s)) return; push(new Item(s, null)); } private void pushByLocalStore(int register) { Item it = pop(); setLVValue( register, it ); } private void pushByLocalLoad(String signature, int register) { Item it = getLVValue(register); if (it == null) push(new Item(signature)); else push(it); } private void setLVValue(int index, Item value ) { int addCount = index - lvValues.size() + 1; while ((addCount--) > 0) lvValues.add(null); lvValues.set(index, value ); } private Item getLVValue(int index) { if (index >= lvValues.size()) return null; return lvValues.get(index); }}// vim:ts=4
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -