alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (Instruction.java)

This example Java source code file (Instruction.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

compilererror, enumeration, float, instruction, integer, ioexception, label, localvariable, long, number, object, string, switchdata, switchratio, util

The Instruction.java Java example source code

/*
 * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.tools.asm;

import sun.tools.java.*;
import java.util.Enumeration;
import java.io.IOException;
import java.io.DataOutputStream;

/**
 * An Java instruction
 *
 * WARNING: The contents of this source file are not part of any
 * supported API.  Code that depends on them does so at its own risk:
 * they are subject to change or removal without notice.
 */
public
class Instruction implements Constants {
    long where;
    int pc;
    int opc;
    Object value;
    Instruction next;
//JCOV
    boolean flagCondInverted;        /* if true, the condition  is reversed
                                   relatively of source code */
    boolean flagNoCovered = false; /* if true, the command will
                                   ignored for coverage */


    /**
     * Constructor
     */
    public Instruction(long where, int opc, Object value, boolean flagCondInverted) {
        this.where = where;
        this.opc = opc;
        this.value = value;
        this.flagCondInverted = flagCondInverted;
    }

    /**
     * Constructor
     */
    public Instruction(boolean flagNoCovered, long where, int opc, Object value) {
        this.where = where;
        this.opc = opc;
        this.value = value;
        this.flagNoCovered = flagNoCovered;
    }

    /**
     * Constructor
     */
    public Instruction(long where, int opc, boolean flagNoCovered) {
        this.where = where;
        this.opc = opc;
        this.flagNoCovered = flagNoCovered;
    }
//end JCOV

    /**
     * Constructor
     */
    public Instruction(long where, int opc, Object value) {
        this.where = where;
        this.opc = opc;
        this.value = value;
    }

    /**
     * When deciding between a lookupswitch and a tableswitch, this
     * value is used in determining how much size increase is
     * acceptable.
     */
    public static final double SWITCHRATIO;

    static {
        // Set SWITCHRATIO from the property javac.switchratio
        // if it exists and is reasonable.  Otherwise, set
        // SWITCHRATIO to 1.5, meaning that we will accept a 1.5x
        // blowup (for the instruction) to use a tableswitch instead
        // of a lookupswitch.
        double ratio = 1.5;
        String valStr = System.getProperty("javac.switchratio");
        if (valStr != null) {
            try {
                double temp = Double.valueOf(valStr).doubleValue();
                if (!(Double.isNaN(temp) || temp < 0.0)) {
                    ratio = temp;
                }
            } catch (NumberFormatException ee) {}
        }
        SWITCHRATIO = ratio;
    }

    /**
     * Accessor
     */
    public int getOpcode() {
        return pc;
     }

    public Object getValue() {
        return value;
     }

    public void setValue(Object value) {
        this.value = value;
     }


    /**
     * Optimize
     */
    void optimize(Environment env) {
        switch (opc) {
          case opc_istore: case opc_lstore: case opc_fstore:
          case opc_dstore: case opc_astore:
            // Don't keep the LocalVariable info around, unless we
            // are actually going to generate a local variable table.
            if ((value instanceof LocalVariable) && !env.debug_vars()) {
                value = new Integer(((LocalVariable)value).slot);
            }
            break;

          case opc_goto: {
            Label lbl = (Label)value;
            value = lbl = lbl.getDestination();
            if (lbl == next) {
                // goto to the next instruction, obsolete
                opc = opc_dead;
                break;
            }

            // We optimize
            //
            //          goto Tag
            //          ...
            //    Tag:
            //          return
            //
            // except when we're generating debuggable code.  When
            // we're generating debuggable code, we leave it alone,
            // in order to provide better stepping behavior.  Consider
            // a method the end of which looks like this:
            //
            //          ...
            //          break;
            //      }   // end of loop
            //  }   // end of method
            //
            // If we optimize the goto away, we'll be left with a
            // single instruction (return) and the need to ascribe that
            // instruction to two source lines (the break statement and
            // the method's right curly).  Can't get there from here.
            // Depending on which line-number ascription we choose, the
            // stepping user will step directly from the break statement
            // back into the caller of the method (case 1) or from the
            // statement that precedes the break statement to the method's
            // right curly (case 2).  Similarly, he'll be able to set a
            // breakpoint on the break statement (case 1) or the method's
            // right curly (case 2), but not on both.  Neither case 1 nor
            // case 2 is desirable.  .We want him to see both the break
            // statement and the method's right curly when stepping,
            // and we want him to be able to set a breakpoint on either or
            // both.  So we suppress the optimization when generating
            // debuggable code.
            // (Above notes from brucek@eng in JDK1.0.2, copied here
            //  by kelly.ohair@eng for JDK1.1)
            //
            // With the changes to allow -O and -g at the same time,
            // I've changed the condition to be whether optimization is
            // on instead of the debugging flag being off.
            //     - david.stoutamire@eng for 1.2

            if (lbl.next != null && env.opt()) {
                switch (lbl.next.opc) {
                  case opc_return:  case opc_ireturn: case opc_lreturn:
                  case opc_freturn: case opc_dreturn: case opc_areturn:
                    // goto to return
                    opc = lbl.next.opc;
                    value = lbl.next.value;
                    break;
                }
            }
            break;
          }

          case opc_ifeq:   case opc_ifne:   case opc_ifgt:
          case opc_ifge:   case opc_iflt:   case opc_ifle:
          case opc_ifnull: case opc_ifnonnull:
            value = ((Label)value).getDestination();
            if (value == next) {
                // branch to next instruction, obsolete
                opc = opc_pop;
                break;
            }
            if ((next.opc == opc_goto) && (value == next.next)) {
                // Conditional branch over goto, invert
                // Note that you can't invert all conditions, condition
                // results for float/double compares are not invertable.
                switch (opc) {
                  case opc_ifeq:      opc = opc_ifne; break;
                  case opc_ifne:      opc = opc_ifeq; break;
                  case opc_iflt:      opc = opc_ifge; break;
                  case opc_ifle:      opc = opc_ifgt; break;
                  case opc_ifgt:      opc = opc_ifle; break;
                  case opc_ifge:      opc = opc_iflt; break;
                  case opc_ifnull:    opc = opc_ifnonnull; break;
                  case opc_ifnonnull: opc = opc_ifnull; break;
                }
//JCOV
                flagCondInverted = !flagCondInverted;
//end JCOV
                value = next.value;
                next.opc = opc_dead;
            }
            break;

          case opc_if_acmpeq:   case opc_if_acmpne:
          case opc_if_icmpeq:   case opc_if_icmpne:
          case opc_if_icmpgt:   case opc_if_icmpge:
          case opc_if_icmplt:   case opc_if_icmple:
            value = ((Label)value).getDestination();
            if (value == next) {
                // branch to next instruction, obsolete
                opc = opc_pop2;
                break;
            }
            if ((next.opc == opc_goto) && (value == next.next)) {
                // Conditional branch over goto, invert
                switch (opc) {
                  case opc_if_acmpeq: opc = opc_if_acmpne; break;
                  case opc_if_acmpne: opc = opc_if_acmpeq; break;
                  case opc_if_icmpeq: opc = opc_if_icmpne; break;
                  case opc_if_icmpne: opc = opc_if_icmpeq; break;
                  case opc_if_icmpgt: opc = opc_if_icmple; break;
                  case opc_if_icmpge: opc = opc_if_icmplt; break;
                  case opc_if_icmplt: opc = opc_if_icmpge; break;
                  case opc_if_icmple: opc = opc_if_icmpgt; break;
                }
//JCOV
                flagCondInverted = !flagCondInverted;
//end JCOV
                value = next.value;
                next.opc = opc_dead;
            }
            break;

          case opc_tableswitch:
          case opc_lookupswitch: {
            SwitchData sw = (SwitchData)value;
            sw.defaultLabel = sw.defaultLabel.getDestination();
            for (Enumeration<Integer> e = sw.tab.keys() ; e.hasMoreElements() ; ) {
                Integer k = e.nextElement();
                Label lbl = sw.tab.get(k);
                sw.tab.put(k, lbl.getDestination());
            }

            // Compute the approximate sizes of a tableswitch and a
            // lookupswitch.  Decide which one we want to generate.

            long range = (long)sw.maxValue - (long)sw.minValue + 1;
            long entries = sw.tab.size();

            long tableSize = 4 + range;
            long lookupSize = 3 + 2 * entries;

            if (tableSize <= lookupSize * SWITCHRATIO) {
                opc = opc_tableswitch;
            } else {
                opc = opc_lookupswitch;
            }
            break;
          }

        }
    }

    /**
     * Collect constants into the constant table
     */
    void collect(ConstantPool tab) {
        switch (opc) {
          case opc_istore:      case opc_lstore:        case opc_fstore:
          case opc_dstore:      case opc_astore:
            if (value instanceof LocalVariable) {
                MemberDefinition field = ((LocalVariable)value).field;
                tab.put(field.getName().toString());
                tab.put(field.getType().getTypeSignature());
            }
            return;

          case opc_new:                 case opc_putfield:
          case opc_putstatic:           case opc_getfield:
          case opc_getstatic:           case opc_invokevirtual:
          case opc_invokespecial:       case opc_invokestatic:
          case opc_invokeinterface:     case opc_instanceof:
          case opc_checkcast:
            tab.put(value);
            return;

          case opc_anewarray:
            tab.put(value);
            return;

          case opc_multianewarray:
            tab.put(((ArrayData)value).type);
            return;

          case opc_ldc:
          case opc_ldc_w:
            if (value instanceof Integer) {
                int v = ((Integer)value).intValue();
                if ((v >= -1) && (v <= 5)) {
                    opc = opc_iconst_0 + v;
                    return;
                } else if ((v >= -(1 << 7)) && (v < (1 << 7))) {
                    opc = opc_bipush;
                    return;
                } else if ((v >= -(1 << 15)) && (v < (1 << 15))) {
                    opc = opc_sipush;
                    return;
                }
            } else if (value instanceof Float) {
                float v = ((Float)value).floatValue();
                if (v == 0) {
                    if (Float.floatToIntBits(v) == 0) {
                        opc = opc_fconst_0;
                        return;
                    }
                } else if (v == 1) {
                    opc = opc_fconst_1;
                    return;
                } else if (v == 2) {
                    opc = opc_fconst_2;
                    return;
                }
            }
            tab.put(value);
            return;

          case opc_ldc2_w:
            if (value instanceof Long) {
                long v = ((Long)value).longValue();
                if (v == 0) {
                    opc = opc_lconst_0;
                    return;
                } else if (v == 1) {
                    opc = opc_lconst_1;
                    return;
                }
            } else if (value instanceof Double) {
                double v = ((Double)value).doubleValue();
                if (v == 0) {
                    if (Double.doubleToLongBits(v) == 0) {
                        opc = opc_dconst_0;
                        return;
                    }
                } else if (v == 1) {
                    opc = opc_dconst_1;
                    return;
                }
            }
            tab.put(value);
            return;

          case opc_try:
            for (Enumeration<CatchData> e = ((TryData)value).catches.elements() ; e.hasMoreElements() ;) {
                CatchData cd = e.nextElement();
                if (cd.getType() != null) {
                    tab.put(cd.getType());
                }
            }
            return;

          case opc_nop:
            if ((value != null) && (value instanceof ClassDeclaration))
                tab.put(value);
                return;
        }
    }

    /**
     * Balance the stack
     */
    int balance() {
        switch (opc) {
          case opc_dead:        case opc_label:         case opc_iinc:
          case opc_arraylength: case opc_laload:        case opc_daload:
          case opc_nop:         case opc_ineg:          case opc_fneg:
          case opc_lneg:        case opc_dneg:          case opc_i2f:
          case opc_f2i:         case opc_l2d:           case opc_d2l:
          case opc_i2b:         case opc_i2c:           case opc_i2s:
          case opc_jsr:         case opc_goto:          case opc_jsr_w:
          case opc_goto_w:      case opc_return:        case opc_ret:
          case opc_instanceof:  case opc_checkcast:     case opc_newarray:
          case opc_anewarray:   case opc_try:           case opc_swap:
            return 0;

          case opc_ldc:         case opc_ldc_w:         case opc_bipush:
          case opc_sipush:      case opc_aconst_null:   case opc_iconst_m1:
          case opc_iconst_0:    case opc_iconst_1:      case opc_iconst_2:
          case opc_iconst_3:    case opc_iconst_4:      case opc_iconst_5:
          case opc_fconst_0:    case opc_fconst_1:      case opc_fconst_2:
          case opc_iload:       case opc_fload:         case opc_aload:
          case opc_dup:         case opc_dup_x1:        case opc_dup_x2:
          case opc_i2l:         case opc_i2d:           case opc_f2l:
          case opc_f2d:         case opc_new:
            return 1;

          case opc_lload:       case opc_dload:         case opc_dup2:
          case opc_dup2_x1:     case opc_dup2_x2:       case opc_ldc2_w:
          case opc_lconst_0:    case opc_lconst_1:      case opc_dconst_0:
          case opc_dconst_1:
            return 2;

          case opc_istore:      case opc_fstore:        case opc_astore:
          case opc_iaload:      case opc_faload:        case opc_aaload:
          case opc_baload:      case opc_caload:        case opc_saload:
          case opc_pop:         case opc_iadd:          case opc_fadd:
          case opc_isub:        case opc_fsub:          case opc_imul:
          case opc_fmul:        case opc_idiv:          case opc_fdiv:
          case opc_irem:        case opc_frem:          case opc_ishl:
          case opc_ishr:        case opc_iushr:         case opc_lshl:
          case opc_lshr:        case opc_lushr:         case opc_iand:
          case opc_ior:         case opc_ixor:          case opc_l2i:
          case opc_l2f:         case opc_d2i:           case opc_d2f:
          case opc_ifeq:        case opc_ifne:          case opc_iflt:
          case opc_ifle:        case opc_ifgt:          case opc_ifge:
          case opc_ifnull:      case opc_ifnonnull:     case opc_fcmpl:
          case opc_fcmpg:       case opc_ireturn:       case opc_freturn:
          case opc_areturn:     case opc_tableswitch:   case opc_lookupswitch:
          case opc_athrow:      case opc_monitorenter:  case opc_monitorexit:
            return -1;

          case opc_lstore:      case opc_dstore:        case opc_pop2:
          case opc_ladd:        case opc_dadd:          case opc_lsub:
          case opc_dsub:        case opc_lmul:          case opc_dmul:
          case opc_ldiv:        case opc_ddiv:          case opc_lrem:
          case opc_drem:        case opc_land:          case opc_lor:
          case opc_lxor:        case opc_if_acmpeq:     case opc_if_acmpne:
          case opc_if_icmpeq:   case opc_if_icmpne:     case opc_if_icmplt:
          case opc_if_icmple:   case opc_if_icmpgt:     case opc_if_icmpge:
          case opc_lreturn:     case opc_dreturn:
            return -2;

          case opc_iastore:     case opc_fastore:       case opc_aastore:
          case opc_bastore:     case opc_castore:       case opc_sastore:
          case opc_lcmp:        case opc_dcmpl:         case opc_dcmpg:
            return -3;

          case opc_lastore:     case opc_dastore:
            return -4;

          case opc_multianewarray:
            return 1 - ((ArrayData)value).nargs;

          case opc_getfield:
            return ((MemberDefinition)value).getType().stackSize() - 1;

          case opc_putfield:
            return -1 - ((MemberDefinition)value).getType().stackSize();

          case opc_getstatic:
            return ((MemberDefinition)value).getType().stackSize();

          case opc_putstatic:
            return -((MemberDefinition)value).getType().stackSize();

          case opc_invokevirtual:
          case opc_invokespecial:
          case opc_invokeinterface:
            return ((MemberDefinition)value).getType().getReturnType().stackSize() -
                   (((MemberDefinition)value).getType().stackSize() + 1);

          case opc_invokestatic:
            return ((MemberDefinition)value).getType().getReturnType().stackSize() -
                   (((MemberDefinition)value).getType().stackSize());
        }
        throw new CompilerError("invalid opcode: " + toString());
    }

    /**
     * Return the size of the instruction
     */
    int size(ConstantPool tab) {
        switch (opc) {
          case opc_try:         case opc_label:         case opc_dead:
            return 0;

          case opc_bipush:      case opc_newarray:
            return 2;

          case opc_sipush:      case opc_goto:          case opc_jsr:
          case opc_ifeq:        case opc_ifne:          case opc_ifgt:
          case opc_ifge:        case opc_iflt:          case opc_ifle:
          case opc_ifnull:      case opc_ifnonnull:     case opc_if_acmpeq:
          case opc_if_acmpne:   case opc_if_icmpeq:     case opc_if_icmpne:
          case opc_if_icmpgt:   case opc_if_icmpge:     case opc_if_icmplt:
          case opc_if_icmple:
            return 3;

          case opc_ldc:
          case opc_ldc_w:
            if (tab.index(value) < 256) {
                opc = opc_ldc;
                return 2;
            } else {
                opc = opc_ldc_w;
                return 3;
            }

          case opc_iload:       case opc_lload:         case opc_fload:
          case opc_dload:       case opc_aload: {
            int v = ((Number)value).intValue();
            if (v < 4) {
                if (v < 0) {
                    throw new CompilerError("invalid slot: " + toString()
                        + "\nThis error possibly resulted from poorly constructed class paths.");
                }
                opc = opc_iload_0 + (opc - opc_iload) * 4 + v;
                return 1;
            } else if (v <= 255) {
                return 2;
            } else {
                opc += 256;     // indicate wide variant
                return 4;
            }
          }

           case opc_iinc: {
               int register = ((int[])value)[0];
               int increment = ((int[])value)[1];
               if (register < 0) {
                   throw new CompilerError("invalid slot: " + toString());
               }
               if (register <= 255 && (((byte)increment) == increment)) {
                   return 3;
               } else {
                   opc += 256;          // indicate wide variant
                   return 6;
               }
           }

          case opc_istore:      case opc_lstore:        case opc_fstore:
          case opc_dstore:      case opc_astore: {
            int v = (value instanceof Number) ?
                ((Number)value).intValue() : ((LocalVariable)value).slot;
            if (v < 4) {
                if (v < 0) {
                    throw new CompilerError("invalid slot: " + toString());
                }
                opc = opc_istore_0 + (opc - opc_istore) * 4 + v;
                return 1;
            } else if (v <= 255) {
                return 2;
            } else {
                opc += 256;     // indicate wide variant
                return 4;
            }
          }

          case opc_ret: {
              int v = ((Number)value).intValue();
              if (v <= 255) {
                  if (v < 0) {
                      throw new CompilerError("invalid slot: " + toString());
                  }
                  return 2;
              } else {
                  opc += 256;   // indicate wide variant
                  return 4;
              }
          }

          case opc_ldc2_w:              case opc_new:
          case opc_putstatic:           case opc_getstatic:
          case opc_putfield:            case opc_getfield:
          case opc_invokevirtual:       case opc_invokespecial:
          case opc_invokestatic:        case opc_instanceof:
          case opc_checkcast:           case opc_anewarray:
            return 3;

          case opc_multianewarray:
            return 4;

          case opc_invokeinterface:
          case opc_goto_w:
          case opc_jsr_w:
            return 5;

          case opc_tableswitch: {
            SwitchData sw = (SwitchData)value;
            int n = 1;
            for(; ((pc + n) % 4) != 0 ; n++);
            return n + 16 + (sw.maxValue - sw.minValue) * 4;
          }

          case opc_lookupswitch: {
            SwitchData sw = (SwitchData)value;
            int n = 1;
            for(; ((pc + n) % 4) != 0 ; n++);
            return n + 8 + sw.tab.size() * 8;
          }

          case opc_nop:
            if ((value != null) && !(value instanceof Integer))
                return 2;
            else
                return 1;
        }

        // most opcodes are only 1 byte long
        return 1;
    }

    /**
     * Generate code
     */
    @SuppressWarnings("fallthrough")
    void write(DataOutputStream out, ConstantPool tab) throws IOException {
        switch (opc) {
          case opc_try:         case opc_label:         case opc_dead:
            break;

          case opc_bipush:      case opc_newarray:
          case opc_iload:       case opc_lload:         case opc_fload:
          case opc_dload:       case opc_aload:         case opc_ret:
            out.writeByte(opc);
            out.writeByte(((Number)value).intValue());
            break;

          case opc_iload + 256:         case opc_lload + 256:
          case opc_fload + 256:         case opc_dload + 256:
          case opc_aload + 256:         case opc_ret   + 256:
            out.writeByte(opc_wide);
            out.writeByte(opc - 256);
            out.writeShort(((Number)value).intValue());
            break;

          case opc_istore:      case opc_lstore:        case opc_fstore:
          case opc_dstore:      case opc_astore:
            out.writeByte(opc);
            out.writeByte((value instanceof Number) ?
                          ((Number)value).intValue() : ((LocalVariable)value).slot);
            break;

          case opc_istore + 256:        case opc_lstore + 256:
          case opc_fstore + 256:        case opc_dstore + 256:
          case opc_astore + 256:
            out.writeByte(opc_wide);
            out.writeByte(opc - 256);
            out.writeShort((value instanceof Number) ?
                      ((Number)value).intValue() : ((LocalVariable)value).slot);
            break;

          case opc_sipush:
            out.writeByte(opc);
            out.writeShort(((Number)value).intValue());
            break;

          case opc_ldc:
            out.writeByte(opc);
            out.writeByte(tab.index(value));
            break;

          case opc_ldc_w:               case opc_ldc2_w:
          case opc_new:                 case opc_putstatic:
          case opc_getstatic:           case opc_putfield:
          case opc_getfield:            case opc_invokevirtual:
          case opc_invokespecial:       case opc_invokestatic:
          case opc_instanceof:          case opc_checkcast:
            out.writeByte(opc);
            out.writeShort(tab.index(value));
            break;

          case opc_iinc:
            out.writeByte(opc);
            out.writeByte(((int[])value)[0]); // register
            out.writeByte(((int[])value)[1]); // increment
            break;

          case opc_iinc + 256:
            out.writeByte(opc_wide);
            out.writeByte(opc - 256);
            out.writeShort(((int[])value)[0]); // register
            out.writeShort(((int[])value)[1]); // increment
            break;

          case opc_anewarray:
            out.writeByte(opc);
            out.writeShort(tab.index(value));
            break;

          case opc_multianewarray:
            out.writeByte(opc);
            out.writeShort(tab.index(((ArrayData)value).type));
            out.writeByte(((ArrayData)value).nargs);
            break;

          case opc_invokeinterface:
            out.writeByte(opc);
            out.writeShort(tab.index(value));
            out.writeByte(((MemberDefinition)value).getType().stackSize() + 1);
            out.writeByte(0);
            break;

          case opc_goto:        case opc_jsr:           case opc_ifeq:
          case opc_ifne:        case opc_ifgt:          case opc_ifge:
          case opc_iflt:        case opc_ifle:          case opc_ifnull:
          case opc_ifnonnull:   case opc_if_acmpeq:     case opc_if_acmpne:
          case opc_if_icmpeq:   case opc_if_icmpne:     case opc_if_icmpgt:
          case opc_if_icmpge:   case opc_if_icmplt:     case opc_if_icmple:
            out.writeByte(opc);
            out.writeShort(((Instruction)value).pc - pc);
            break;

          case opc_goto_w:
          case opc_jsr_w:
            out.writeByte(opc);
            out.writeLong(((Instruction)value).pc - pc);
            break;

          case opc_tableswitch: {
            SwitchData sw = (SwitchData)value;
            out.writeByte(opc);
            for(int n = 1 ; ((pc + n) % 4) != 0 ; n++) {
                out.writeByte(0);
            }
            out.writeInt(sw.defaultLabel.pc - pc);
            out.writeInt(sw.minValue);
            out.writeInt(sw.maxValue);
            for (int n = sw.minValue ; n <= sw.maxValue ; n++) {
                Label lbl = sw.get(n);
                int target_pc = (lbl != null) ? lbl.pc : sw.defaultLabel.pc;
                out.writeInt(target_pc - pc);
            }
            break;
          }

          case opc_lookupswitch: {
            SwitchData sw = (SwitchData)value;
            out.writeByte(opc);
            int n = pc + 1;
            for(; (n % 4) != 0 ; n++) {
                out.writeByte(0);
            }
            out.writeInt(sw.defaultLabel.pc - pc);
            out.writeInt(sw.tab.size());
            for (Enumeration<Integer> e = sw.sortedKeys(); e.hasMoreElements() ; ) {
                Integer v = e.nextElement();
                out.writeInt(v.intValue());
                out.writeInt(sw.get(v).pc - pc);
            }
            break;
          }

          case opc_nop:
            if (value != null) {
                if (value instanceof Integer)
                    out.writeByte(((Integer)value).intValue());
                else
                    out.writeShort(tab.index(value));
                return;
            }
            // fall through

          default:
            out.writeByte(opc);
            break;
        }
    }

    /**
     * toString
     */
    public String toString() {
        String prefix = (where >> WHEREOFFSETBITS) + ":\t";
        switch (opc) {
          case opc_try:
            return prefix + "try " + ((TryData)value).getEndLabel().hashCode();

          case opc_dead:
            return prefix + "dead";

          case opc_iinc: {
            int register = ((int[])value)[0];
            int increment = ((int[])value)[1];
            return prefix + opcNames[opc] + " " + register + ", " + increment;
          }

          default:
            if (value != null) {
                if (value instanceof Label) {
                    return prefix + opcNames[opc] + " " + value.toString();
                } else if (value instanceof Instruction) {
                    return prefix + opcNames[opc] + " " + value.hashCode();
                } else if (value instanceof String) {
                    return prefix + opcNames[opc] + " \"" + value + "\"";
                } else {
                    return prefix + opcNames[opc] + " " + value;
                }
            } else {
              return prefix + opcNames[opc];
            }
        }
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java Instruction.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.