methodbuilder.java
来自「JiBX是一个为Java提供的XML数据绑定框架。它可以和现存的类一起运行」· Java 代码 · 共 1,732 行 · 第 1/4 页
JAVA
1,732 行
/** * Verify the top value in the stack state resulting from the current * instruction list is an array. * * @return array item type */ private String verifyArray() { verifyStackDepth(1); String type = m_stackState.peek(); if (type.endsWith("[]")) { return type.substring(0, type.length()-2); } else { throw new IllegalStateException ("Internal error: Expected array type on stack , found " + type); } } /** * Verify the top value in the stack state resulting from the current * instruction list is an array of the specified type. * * @param type array item type */ private void verifyArray(String type) { String atype = verifyArray(); if (!atype.equals(type)) { throw new IllegalStateException ("Internal error: Expected array of " + type + " on stack , found array of " + atype); } } /** * Verify the top two values in the stack state resulting from the current * instruction list. * * @param t1 expected type for first item on stack * @param t2 expected type for second item on stack */ private void verifyStack(String t1, String t2) { verifyStackDepth(2); verifyCompatible(m_stackState.peek(), t1); verifyCompatible(m_stackState.peek(1), t2); } /** * Verify the top values in the stack state resulting from the current * instruction list. This form checks only the actual call parameters. * * @param types expected parameter types on stack */ private void verifyCallStack(String[] types) { // make sure there are enough items on stack int count = types.length; verifyStackDepth(count); // verify all parameter types for call for (int i = 0; i < count; i++) { int slot = count - i - 1; verifyCompatible(m_stackState.peek(slot), types[i]); } } /** * Verify the top values in the stack state resulting from the current * instruction list. This form checks both the object being called and the * actual call parameters. * * @param clas name of method class * @param types expected parameter types on stack */ private void verifyCallStack(String clas, String[] types) { // start by verifying object reference int count = types.length; verifyStackDepth(count+1); verifyCompatible(m_stackState.peek(count), clas); // check values for call parameters verifyCallStack(types); } /** * Verify that the top value in the stack state resulting from the current * instruction list is an object reference. */ private void verifyStackObject() { verifyStackDepth(1); String top = m_stackState.peek(); if (ClassItem.isPrimitive(top)) { throw new IllegalStateException("Internal error: " + "Expected object reference on stack , found " + m_stackState.peek() + "\n full stack:\n" + describeStack()); } } /** * Append IFEQ branch instruction to method. * * @param src object responsible for generating branch * @return wrapper for appended conditional branch */ public BranchWrapper appendIFEQ(Object src) { verifyStack("int"); BranchHandle hand = m_instructionList.append(new IFEQ(null)); setTarget(hand); m_stackState.pop(); return new BranchWrapper(hand, m_stackState.toArray(), src); } /** * Append IFGE branch instruction to method. * * @param src object responsible for generating branch * @return wrapper for appended conditional branch */ public BranchWrapper appendIFGE(Object src) { verifyStack("int"); BranchHandle hand = m_instructionList.append(new IFGE(null)); setTarget(hand); m_stackState.pop(); return new BranchWrapper(hand, m_stackState.toArray(), src); } /** * Append IFLT branch instruction to method. * * @param src object responsible for generating branch * @return wrapper for appended conditional branch */ public BranchWrapper appendIFLT(Object src) { verifyStack("int"); BranchHandle hand = m_instructionList.append(new IFLT(null)); setTarget(hand); m_stackState.pop(); return new BranchWrapper(hand, m_stackState.toArray(), src); } /** * Append IFNE branch instruction to method. * * @param src object responsible for generating branch * @return wrapper for appended conditional branch */ public BranchWrapper appendIFNE(Object src) { verifyStack("int"); BranchHandle hand = m_instructionList.append(new IFNE(null)); setTarget(hand); m_stackState.pop(); return new BranchWrapper(hand, m_stackState.toArray(), src); } /** * Append IFNONNULL branch instruction to method. * * @param src object responsible for generating branch * @return wrapper for appended conditional branch */ public BranchWrapper appendIFNONNULL(Object src) { verifyStackObject(); BranchHandle hand = m_instructionList.append(new IFNONNULL(null)); setTarget(hand); m_stackState.pop(); return new BranchWrapper(hand, m_stackState.toArray(), src); } /** * Append IFNULL branch instruction to method. * * @param src object responsible for generating branch * @return wrapper for appended conditional branch */ public BranchWrapper appendIFNULL(Object src) { verifyStackObject(); BranchHandle hand = m_instructionList.append(new IFNULL(null)); setTarget(hand); m_stackState.pop(); return new BranchWrapper(hand, m_stackState.toArray(), src); } /** * Append IF_ICMPNE branch instruction to method. * * @param src object responsible for generating branch * @return wrapper for appended conditional branch */ public BranchWrapper appendIF_ICMPNE(Object src) { verifyStack("int", "int"); BranchHandle hand = m_instructionList.append(new IF_ICMPNE(null)); setTarget(hand); m_stackState.pop(2); return new BranchWrapper(hand, m_stackState.toArray(), src); } /** * Append unconditional branch instruction to method. * * @param src object responsible for generating branch * @return wrapper for appended unconditional branch */ public BranchWrapper appendUnconditionalBranch(Object src) { BranchHandle hand = m_instructionList.append(new GOTO(null)); setTarget(hand); BranchWrapper wrapper = new BranchWrapper(hand, m_stackState.toArray(), src); m_stackState = null; return wrapper; } /** * Append compound instruction to method. * * @param ins instruction to be appended */ private void append(CompoundInstruction ins) { setTarget(m_instructionList.append(ins)); } /** * Append instruction to method. * * @param ins instruction to be appended */ private void append(Instruction ins) { setTarget(m_instructionList.append(ins)); } /** * Create load constant instruction and append to method. Builds the most * appropriate type of instruction for the value. * * @param value constant value to be loaded */ public void appendLoadConstant(int value) { append(m_instructionBuilder.createLoadConstant(value)); m_stackState.push("int"); } /** * Create load constant instruction and append to method. Loads a * <code>String</code> reference from the constant pool. * * @param value constant value to be loaded */ public void appendLoadConstant(String value) { append(m_instructionBuilder.createLoadConstant(value)); m_stackState.push("java.lang.String"); } /** * Create load constant instruction and append to method. Loads an * unwrapped primitive value from the constant pool. * * @param value constant value to be loaded */ public void appendLoadConstant(Object value) { append(m_instructionBuilder.createLoadConstant(value)); if (value instanceof Integer || value instanceof Character || value instanceof Short || value instanceof Boolean || value instanceof Byte) { m_stackState.push("int"); } else if (value instanceof Long) { m_stackState.push("long"); } else if (value instanceof Float) { m_stackState.push("float"); } else if (value instanceof Double) { m_stackState.push("double"); } else { throw new IllegalArgumentException("Unknown argument type"); } } /** * Create getfield instruction and append to method. Uses the target field * information to generate the instruction. * * @param item information for field to be gotton */ public void appendGetField(ClassItem item) { verifyStack(item.getClassFile().getName()); append(m_instructionBuilder.createGetField(item)); m_stackState.pop(); m_stackState.push(item.getTypeName()); } /** * Create getstatic instruction and append to method. Uses the target field * information to generate the instruction. * * @param item information for field to be set */ public void appendGetStatic(ClassItem item) { append(m_instructionBuilder.createGetStatic(item)); m_stackState.push(item.getTypeName()); } /** * Create get instruction and append to method. This generates either a * getstatic or a getfield instruction, as appropriate. * * @param item information for field to be gotten */ public void appendGet(ClassItem item) { if (item.isStatic()) { appendGetStatic(item); } else { appendGetField(item); } } /** * Create putfield instruction and append to method. Uses the target field * information to generate the instruction. * * @param item information for field to be set */ public void appendPutField(ClassItem item) { String tname = item.getTypeName(); verifyStack(tname, item.getClassFile().getName()); append(m_instructionBuilder.createPutField(item)); m_stackState.pop(2); } /** * Create putstatic instruction and append to method. Uses the target field * information to generate the instruction. * * @param item information for field to be set */ public void appendPutStatic(ClassItem item) { verifyStack(item.getTypeName()); append(m_instructionBuilder.createPutStatic(item)); m_stackState.pop(); } /** * Create put instruction and append to method. This generates either a * putstatic or a putfield instruction, as appropriate. * * @param item information for field to be gotten */ public void appendPut(ClassItem item) { if (item.isStatic()) { appendPutStatic(item); } else { appendPutField(item); } } /** * Create invoke instruction for static, member, or interface method and * append to method. Uses the target method information to generate the * correct instruction. * * @param item information for method to be called */ public void appendCall(ClassItem item) { // process based on call type String[] types = item.getArgumentTypes(); int count = types.length; if (item.getClassFile().isInterface()) { // process parameters and object reference for interface call verifyCallStack(item.getClassFile().getName(), types); append(m_instructionBuilder.createCallInterface(item)); m_stackState.pop(count+1); } else if ((item.getAccessFlags() & Constants.ACC_STATIC) != 0) { // process only parameters for static call verifyCallStack(types); append(m_instructionBuilder.createCallStatic(item)); if (count > 0) { m_stackState.pop(count); } } else { // process parameters and object reference for normal method call verifyCallStack(item.getClassFile().getName(), types); append(m_instructionBuilder.createCallVirtual(item)); m_stackState.pop(count+1); } // adjust stack state to reflect result of call if (!"void".equals(item.getTypeName())) { m_stackState.push(item.getTypeName()); } } /** * Create invoke static method instruction from signature and append to * method. * * @param method fully qualified class and method name * @param signature method signature in standard form */ public void appendCallStatic(String method, String signature) { // verify all call parameters on stack String[] types = ClassItem.getParametersFromSignature(signature); verifyCallStack(types); // generate the actual method call append(m_instructionBuilder.createCallStatic(method, signature)); // change stack state to reflect result of call if (types.length > 0) { m_stackState.pop(types.length); } String result = ClassItem.getTypeFromSignature(signature); if (!"void".equals(result)) { m_stackState.push(result); } } /** * Create invoke virtual method instruction from signature and append to * method. * * @param method fully qualified class and method name * @param signature method signature in standard form */ public void appendCallVirtual(String method, String signature) { // verify all call parameters and object reference on stack String[] types = ClassItem.getParametersFromSignature(signature); int split = method.lastIndexOf('.'); if (split < 0) { throw new IllegalArgumentException
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?