Is the given instruction a read of a field?

@param ins
the Instruction to check
@param cpg
ConstantPoolGen of the method containing the instruction
@return the Field if the instruction is a read of a field, null otherwise
439118
public static FieldAnnotation isRead(Instruction ins, ConstantPoolGen cpg) {
        if (ins instanceof GETFIELD || ins instanceof GETSTATIC) {
            FieldInstruction fins = (FieldInstruction) ins;
            String className = fins.getClassName(cpg);
            return new FieldAnnotation(className, fins.getName(cpg), fins.getSignature(cpg), fins instanceof GETSTATIC);
        } else {
            return null;
        }
    }
89657
NameAndType readNameAndType(int i) {
        Object obj = readPool(i);
        if (obj != null && !(obj instanceof NameAndType))
            throw badClassFile("bad.const.pool.entry",
                               currentClassFile.toString(),
                               "CONSTANT_NameAndType_info", i);
        return (NameAndType)obj;
    }
1169194
@Nullable
  private static Object convertPrimitiveField(Group g, int fieldIndex, int index, boolean binaryAsString)
  {
    PrimitiveType pt = (PrimitiveType) g.getType().getFields().get(fieldIndex);
    OriginalType ot = pt.getOriginalType();

    try {
      if (ot != null) {
        // convert logical types
        switch (ot) {
          case DATE:
            long ts = g.getInteger(fieldIndex, index) * MILLIS_IN_DAY;
            return ts;
          case TIME_MICROS:
            return g.getLong(fieldIndex, index);
          case TIME_MILLIS:
            return g.getInteger(fieldIndex, index);
          case TIMESTAMP_MICROS:
            return TimeUnit.MILLISECONDS.convert(g.getLong(fieldIndex, index), TimeUnit.MICROSECONDS);
          case TIMESTAMP_MILLIS:
            return g.getLong(fieldIndex, index);
          case INTERVAL:
          /*
          INTERVAL is used for an interval of time. It must annotate a fixed_len_byte_array of length 12.
          This array stores three little-endian unsigned integers that represent durations at different
          granularities of time. The first stores a number in months, the second stores a number in days,
          and the third stores a number in milliseconds. This representation is independent of any particular
          timezone or date.

          Each component in this representation is independent of the others. For example, there is no
          requirement that a large number of days should be expressed as a mix of months and days because there is
          not a constant conversion from days to months.

          The sort order used for INTERVAL is undefined. When writing data, no min/max statistics should be
           saved for this type and if such non-compliant statistics are found during reading, they must be ignored.
           */
            Binary intervalVal = g.getBinary(fieldIndex, index);
            IntBuffer intBuf = intervalVal.toByteBuffer().order(ByteOrder.LITTLE_ENDIAN).asIntBuffer();
            int months = intBuf.get(0);
            int days = intBuf.get(1);
            int millis = intBuf.get(2);
            StringBuilder periodBuilder = new StringBuilder("P");
            if (months > 0) {
              periodBuilder.append(months).append("M");
            }
            if (days > 0) {
              periodBuilder.append(days).append("D");
            }
            if (periodBuilder.length() > 1) {
              Period p = Period.parse(periodBuilder.toString());
              Duration d = p.toStandardDuration().plus(millis);
              return d;
            } else {
              return new Duration(millis);
            }
          case INT_8:
          case INT_16:
          case INT_32:
            return g.getInteger(fieldIndex, index);
          case INT_64:
            return g.getLong(fieldIndex, index);
          // todo: idk wtd about unsigned
          case UINT_8:
          case UINT_16:
          case UINT_32:
            return g.getInteger(fieldIndex, index);
          case UINT_64:
            return g.getLong(fieldIndex, index);
          case DECIMAL:
          /*
            DECIMAL can be used to annotate the following types:
              int32: for 1 <= precision <= 9
              int64: for 1 <= precision <= 18; precision < 10 will produce a warning
              fixed_len_byte_array: precision is limited by the array size. Length n can
                store <= floor(log_10(2^(8*n - 1) - 1)) base-10 digits
              binary: precision is not limited, but is required. The minimum number of bytes to store
                the unscaled value should be used.
           */
            int precision = pt.asPrimitiveType().getDecimalMetadata().getPrecision();
            int scale = pt.asPrimitiveType().getDecimalMetadata().getScale();
            switch (pt.getPrimitiveTypeName()) {
              case INT32:
                return new BigDecimal(g.getInteger(fieldIndex, index));
              case INT64:
                return new BigDecimal(g.getLong(fieldIndex, index));
              case FIXED_LEN_BYTE_ARRAY:
              case BINARY:
                Binary value = g.getBinary(fieldIndex, index);
                return convertBinaryToDecimal(value, precision, scale);
              default:
                throw new RE(
                    "Unknown 'DECIMAL' type supplied to primitive conversion: %s (this should never happen)",
                    pt.getPrimitiveTypeName()
                );
            }
          case UTF8:
          case ENUM:
          case JSON:
            return g.getString(fieldIndex, index);
          case LIST:
          case MAP:
          case MAP_KEY_VALUE:
          case BSON:
          default:
            throw new RE(
                "Non-primitive supplied to primitive conversion: %s (this should never happen)",
                ot.name()
            );
        }
      } else {
        // fallback to handling the raw primitive type if no logical type mapping
        switch (pt.getPrimitiveTypeName()) {
          case BOOLEAN:
            return g.getBoolean(fieldIndex, index);
          case INT32:
            return g.getInteger(fieldIndex, index);
          case INT64:
            return g.getLong(fieldIndex, index);
          case FLOAT:
            return g.getFloat(fieldIndex, index);
          case DOUBLE:
            return g.getDouble(fieldIndex, index);
          case INT96:
            Binary tsBin = g.getInt96(fieldIndex, index);
            return convertInt96BinaryToTimestamp(tsBin);
          case FIXED_LEN_BYTE_ARRAY:
          case BINARY:
            Binary bin = g.getBinary(fieldIndex, index);
            byte[] bytes = bin.getBytes();
            if (binaryAsString) {
              return StringUtils.fromUtf8(bytes);
            } else {
              return bytes;
            }
          default:
            throw new RE("Unknown primitive conversion: %s", ot.name());
        }
      }
    }
    catch (Exception ex) {
      return null;
    }
  }
961852
private boolean hasCustomReadObject(Method m, ClassContext classContext,List<String> classesToIgnore)
            throws CFGBuilderException, DataflowAnalysisException {
        ConstantPoolGen cpg = classContext.getConstantPoolGen();
        CFG cfg = classContext.getCFG(m);
        int count = 0;
        for (Iterator<Location> i = cfg.locationIterator(); i.hasNext(); ) {
            Location location = i.next();
            Instruction inst = location.getHandle().getInstruction();
            //ByteCode.printOpCode(inst,cpg);
            if(inst instanceof InvokeInstruction) {
                InvokeInstruction invoke = (InvokeInstruction) inst;
                if (!READ_DESERIALIZATION_METHODS.contains(invoke.getMethodName(cpg))
                        && !classesToIgnore.contains(invoke.getClassName(cpg))) {
                    count +=1;
                }
            }
        }
        return count > 3;
    }
1338594
@Override
  public synchronized void readFields(DataInput in) throws IOException {
    int numClasses = in.readInt();
    groups.clear();
    while (numClasses-- > 0) {
      String groupName = Text.readString(in);
      CounterGroup group = new CounterGroup(groupName);
      group.readFields(in);
      groups.put(groupName, group);
    }
  }
170337
@Override	public List<ICacheKeyGenerator> getCacheKeyGenerators(IAggregator aggregator) {
		final String sourceMethod = "getCacheKeyGenerators"; //$NON-NLS-1$
		final boolean isTraceLogging = log.isLoggable(Level.FINER);
		if (isTraceLogging) {
			log.entering(sourceClass, sourceMethod, new Object[]{aggregator});
		}
		List<ICacheKeyGenerator> result = super.getCacheKeyGenerators(aggregator);
		if (isFeatureDependent) {
			// If responses are feature dependent, add a FeatueCacheKeyGenerator to the list of
			// cache key generators for this module builder
			result = new ArrayList<ICacheKeyGenerator>(super.getCacheKeyGenerators(aggregator));
			if (result.size() != 2) {
				throw new IllegalStateException("Unexpected list size = " + result.size()); //$NON-NLS-1$
			}
			result.add(new FeatureSetCacheKeyGenerator(new HashSet<String>(), true));
			result = Collections.unmodifiableList(result);
		}
		if (isTraceLogging) {
			log.exiting(sourceClass, sourceMethod, KeyGenUtil.toString(result));
		}
		return result;
	}
779825
public void read(LineInput in)
        throws IOException
    {  
        Field last=null;
        char[] buf=null;
        int size=0;
        org.browsermob.proxy.jetty.util.LineInput.LineBuffer line_buffer;
        synchronized(in)
        {
            line:
            while ((line_buffer=in.readLineBuffer())!=null)
            {
                // check space in the lowercase buffer
                buf=line_buffer.buffer;
                size=line_buffer.size;
                if (size==0)
                    break;
                
                // setup loop state machine
                int i1=-1;
                int i2=-1;
                int name_l=0;
                int i=0;
                char c=buf[0];
                
                // Check for continuity line
                if (c!=' ' && c!='\t')
                {
                    i2=0;
                    // reading name upto :
                    for (i=1;i<size;i++)
                    {
                        c=buf[i];
                        if (c==':')
                        {
                            name_l=i2+1; 
                            break;
                        }
                        
                        if (c!=' '&&c!='\t')
                            i2=i;
                    }
                }   

                // skip whitespace after : or start of continuity line
                for (i++;i<size;i++)
                {
                    c=buf[i];
                    if (c!=' ' && c!='\t')
                    {
                        i1=i;
                        i2=i-1;
                        break;
                    }
                }
                
                // Reverse Parse the "name : value" to last char of value
                for (i=size;i-->i1 && i>=0;)
                {
                    c=buf[i];
                    if (c!=' ' && c!='\t')
                    {
                        i2=i;
                        break;
                    }
                }

                // If no name, it is a continuation line
                if (name_l<=0)
                {
                    if (i1>0 && last!=null)
                        last._value=last._value+' '+new String(buf,i1,i2-i1+1);
                    continue;
                }

                // create the field.
                FieldInfo info = getFieldInfo(buf,0,name_l);
                Field field=getField(info,false);
                last=null;
                if (field!=null)
                {
                    while(field!=null && field._version==_version)
                    {
                        last=field;
                        field=field._next;
                    }
                }
                
                if (field!=null)
                {
                    if (i1>=0)
                        field.reset(buf,i1,i2-i1+1,_version);
                    else
                        field.reset("",_version);
                }
                else
                {
                    // create the field
                    if (i1>=0)
                        field=new Field(info,buf,i1,i2-i1+1,_version);
                    else
                        field=new Field(info,"",_version);
                    
                    // look for chain to add too
                    if(last!=null)
                    {
                        field._prev=last;
                        last._next=field; 
                          
                    }
                    else if (info.hashCode()<_index.length)
                        _index[info.hashCode()]=_fields.size(); 
                    _fields.add(field);
                }
                
                last=field;
            }
        }
    }
1113841
private void readObject(java.io.ObjectInputStream in)
        throws java.io.IOException, ClassNotFoundException
    {
        in.defaultReadObject();
        if (_class==null || !_class.getName().equals(_className))
        {
            try
            {
                setPoolClass(Loader.loadClass(Pool.class,_className));
            }
            catch (Exception e)
            {
                log.warn(LogSupport.EXCEPTION,e);
                throw new java.io.InvalidObjectException(e.toString());
            }
        }
    }
305390
private static ICodeGenerator getCodeGenerator(Class cls) {
        // check if has default constructor

        if (!cls.isMemberClass()) {
            try {
                cls.getConstructor(new Class<?>[0]);
            } catch (NoSuchMethodException e2) {
                throw new IllegalArgumentException(
                        "Class '" + cls.getName() + "' must has default constructor method with no parameters.", e2);
            } catch (SecurityException e2) {
                throw new IllegalArgumentException(e2.getMessage(), e2);
            }
        }

        ICodeGenerator cg = new TemplateCodeGenerator(cls);

        return cg;
    }
743459
public static int readInt(DataInput in) throws IOException {
        byte len=in.readByte();
        if(len == 0)
            return 0;
        return makeInt(in, len);
    }
1115818
private static int readLen(InputStream in) throws IOException {
        int c = in.read();
        if (c > 0) {
            if ((c & 0x80) == 0) {
            } else if ((c & 0xC0) == 0x80) {
                c = c & ~0xC0;
                c = (c << 8) | in.read();
            } else if ((c & 0xE0) == 0xC0) {
                c = c & ~0xE0;
                c = (c << 8) | in.read();
                c = (c << 8) | in.read();
            } else if ((c & 0xF0) == 0xE0) {
                c = c & ~0xF0;
                c = (c << 8) | in.read();
                c = (c << 8) | in.read();
                c = (c << 8) | in.read();
            } else if ((c & 0xF8) == 0xF0) {
                c = in.read();
                c = (c << 8) | in.read();
                c = (c << 8) | in.read();
                c = (c << 8) | in.read();
                c = (c << 8) | in.read();
            }
        }
        return c;
    }
1289782
public static int readUnsignedMediumInt(IoBuffer in) {
        final byte a = in.get();
        final byte b = in.get();
        final byte c = in.get();
        int val = 0;
        val += (a & 0xff) << 16;
        val += (b & 0xff) << 8;
        val += (c & 0xff);
        return val;
    }
309444
public void read(ByteCodeParser in)
    throws IOException
  {
    int length = in.readInt();
    
    int exnCount = in.readShort();

    for (int i = 0; i < exnCount; i++) {
      int index = in.readShort();

      if (index == 0) {
        _methods.add(null);
      }
      
      // _methods.add(in.getConstantPool().getClass(index).getName());
    }
  }
242393
private boolean readMetaDataEntry(ReadStream is)
    throws IOException
  {
    int crc = _nonce;
    
    int code = is.read();
    crc = Crc32Caucho.generate(crc, code);
    
    switch (code) {
    case CODE_TABLE:
      readMetaTable(is, crc);
      break;
      
    case CODE_SEGMENT:
      readMetaSegment(is, crc);
      break;
      
    case CODE_META_SEGMENT:
      readMetaContinuation(is, crc);
      break;
      
    default:
      return false;
    }
    
    _metaOffset = is.position();
    
    return true;
  }
868586
public int getInstanceSlot(Instruction ins, ConstantPoolGen cpg) throws DataflowAnalysisException {
        if (!isValid()) {
            throw new DataflowAnalysisException("Accessing invalid frame at " + ins);
        }
        int numConsumed = ins.consumeStack(cpg);
        if (numConsumed == Const.UNPREDICTABLE) {
            throw new DataflowAnalysisException("Unpredictable stack consumption in " + ins);
        }
        if (numConsumed > getStackDepth()) {
            throw new DataflowAnalysisException("Stack underflow " + ins);
        }
        return getNumSlots() - numConsumed;
    }
651868
@Override
    public LoadedFieldSet analyze(IAnalysisCache analysisCache, MethodDescriptor descriptor) throws CheckedAnalysisException {
        MethodGen methodGen = getMethodGen(analysisCache, descriptor);
        if (methodGen == null) {
            return null;
        }
        InstructionList il = methodGen.getInstructionList();

        LoadedFieldSet loadedFieldSet = new LoadedFieldSet(methodGen);
        ConstantPoolGen cpg = getConstantPoolGen(analysisCache, descriptor.getClassDescriptor());

        for (InstructionHandle handle = il.getStart(); handle != null; handle = handle.getNext()) {
            Instruction ins = handle.getInstruction();
            short opcode = ins.getOpcode();
            try {
                if (opcode == Const.INVOKESTATIC) {
                    INVOKESTATIC inv = (INVOKESTATIC) ins;
                    if (Hierarchy.isInnerClassAccess(inv, cpg)) {
                        InnerClassAccess access = Hierarchy.getInnerClassAccess(inv, cpg);
                        /*
                         * if (access == null) {
                         * System.out.println("Missing inner class access in " +
                         * SignatureConverter.convertMethodSignature(methodGen)
                         * + " at " + inv); }
                         */
                        if (access != null) {
                            if (access.isLoad()) {
                                loadedFieldSet.addLoad(handle, access.getField());
                            } else {
                                loadedFieldSet.addStore(handle, access.getField());
                            }
                        }
                    }
                } else if (fieldInstructionOpcodeSet.get(opcode)) {
                    boolean isLoad = (opcode == Const.GETFIELD || opcode == Const.GETSTATIC);
                    XField field = Hierarchy.findXField((FieldInstruction) ins, cpg);
                    if (field != null) {
                        if (isLoad) {
                            loadedFieldSet.addLoad(handle, field);
                        } else {
                            loadedFieldSet.addStore(handle, field);
                        }
                    }
                }
            } catch (ClassNotFoundException e) {
                AnalysisContext.currentAnalysisContext().getLookupFailureCallback().reportMissingClass(e);
            }
        }

        return loadedFieldSet;
    }
564854
public void read_config(InputStream in) throws Exception {

        JsonFactory f = new MappingJsonFactory();
        JsonParser jp = f.createJsonParser(in);

        JsonToken current;

        current = jp.nextToken();
        if (current != JsonToken.START_OBJECT) {
            logger.warn("read_config: Error:  START_OBJECT not found : quiting.");
            return;
        }
        current = jp.nextToken();
        String fieldName = jp.getCurrentName();
        current = jp.nextToken();
        if (fieldName.equals("config")) {
            if (current != JsonToken.START_OBJECT) {
                logger.warn("read_config: Error:  START_OBJECT not found after config : quiting.");
                return;
            }
            current = jp.nextToken();
            String fieldName2 = jp.getCurrentName();
            if (fieldName2.equals("metric_groups")) {
                current = jp.nextToken();
                if (current != JsonToken.START_ARRAY) {
                  logger.warn("read_config: Error:  START_ARRAY not found after metric_groups : quiting.");
                  return;
                }

                current = jp.nextToken();
                while (current != JsonToken.END_ARRAY) {
                    if (current != JsonToken.START_OBJECT) {
                        logger.warn("read_config: Error:  START_OBJECT not found after metric_groups START_ARRAY : quiting.");
                        return;
                    }
                    current = jp.nextToken();
                    JsonNode node1 = jp.readValueAsTree();
                    String node1string = write_tostring(node1);
                    metricgroupMap.put(node1.get("name").asText(),node1string);
                    current = jp.nextToken();
                }

                current = jp.nextToken();
                String fieldName3 = jp.getCurrentName();

                if (fieldName3.equals("dashboards")) {
                    current = jp.nextToken();
                    if (current != JsonToken.START_ARRAY) {
                        logger.warn("read_config: Error:  START_ARRAY not found after dashboards : quiting.");
                        return;
                    }
                    current = jp.nextToken();
                    while (current != JsonToken.END_ARRAY) {
                        if (current != JsonToken.START_OBJECT) {
                            logger.warn("read_config: Error:  START_OBJECT not found after dashboards START_ARRAY : quiting.");
                            return;
                        }
                        current = jp.nextToken();
                        JsonNode node = jp.readValueAsTree();
                        String nodestring = write_tostring(node);
                        dashMap.put(node.get("name").asText(),nodestring);
                        current = jp.nextToken();

                    }
                    if(jp.nextToken() != JsonToken.END_OBJECT) {
                        logger.warn("read_config: Error:  END_OBJECT expected, not found (1): quiting.");
                        return;
                    }
                    if(jp.nextToken() != JsonToken.END_OBJECT) {
                        logger.warn("read_config: Error:  END_OBJECT expected, not found (2): quiting.");
                        return;
                    }
                } else {
                    logger.warn("read_config: Error:  Expected dashboards : quiting.");
                    return;
                }
            } else {
                logger.warn("read_config: Error:  Expected metric_groups : quiting.");
                return;
            }
        }
    }