All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ibm.wala.classLoader.JavaLanguage Maven / Gradle / Ivy

/*
 * Copyright (c) 2009 IBM Corporation.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *
 */
package com.ibm.wala.classLoader;

import com.ibm.wala.analysis.typeInference.JavaPrimitiveType;
import com.ibm.wala.analysis.typeInference.PrimitiveType;
import com.ibm.wala.core.util.shrike.Exceptions.MethodResolutionFailure;
import com.ibm.wala.core.util.shrike.ShrikeUtil;
import com.ibm.wala.core.util.strings.Atom;
import com.ibm.wala.core.util.warnings.Warnings;
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.IAnalysisCacheView;
import com.ibm.wala.ipa.callgraph.impl.AbstractRootMethod;
import com.ibm.wala.ipa.callgraph.impl.FakeRootClass;
import com.ibm.wala.ipa.callgraph.impl.FakeRootMethod;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.ipa.modref.ExtendedHeapModel;
import com.ibm.wala.ipa.modref.ModRef.ModVisitor;
import com.ibm.wala.ipa.modref.ModRef.RefVisitor;
import com.ibm.wala.shrike.shrikeBT.ConstantInstruction;
import com.ibm.wala.shrike.shrikeBT.ConstantInstruction.ClassToken;
import com.ibm.wala.shrike.shrikeBT.Constants;
import com.ibm.wala.shrike.shrikeBT.IBinaryOpInstruction;
import com.ibm.wala.shrike.shrikeBT.IComparisonInstruction;
import com.ibm.wala.shrike.shrikeBT.IConditionalBranchInstruction;
import com.ibm.wala.shrike.shrikeBT.IInstruction;
import com.ibm.wala.shrike.shrikeBT.IInvokeInstruction;
import com.ibm.wala.shrike.shrikeBT.IUnaryOpInstruction;
import com.ibm.wala.shrike.shrikeBT.Instruction;
import com.ibm.wala.shrike.shrikeCT.BootstrapMethodsReader.BootstrapMethod;
import com.ibm.wala.shrike.shrikeCT.ConstantPoolParser.ReferenceToken;
import com.ibm.wala.shrike.shrikeCT.InvalidClassFileException;
import com.ibm.wala.ssa.SSAAbstractBinaryInstruction;
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
import com.ibm.wala.ssa.SSAAddressOfInstruction;
import com.ibm.wala.ssa.SSAArrayLengthInstruction;
import com.ibm.wala.ssa.SSAArrayLoadInstruction;
import com.ibm.wala.ssa.SSAArrayStoreInstruction;
import com.ibm.wala.ssa.SSABinaryOpInstruction;
import com.ibm.wala.ssa.SSACheckCastInstruction;
import com.ibm.wala.ssa.SSAComparisonInstruction;
import com.ibm.wala.ssa.SSAConditionalBranchInstruction;
import com.ibm.wala.ssa.SSAConversionInstruction;
import com.ibm.wala.ssa.SSAGetCaughtExceptionInstruction;
import com.ibm.wala.ssa.SSAGetInstruction;
import com.ibm.wala.ssa.SSAGotoInstruction;
import com.ibm.wala.ssa.SSAInstanceofInstruction;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.ssa.SSAInstructionFactory;
import com.ibm.wala.ssa.SSAInvokeDynamicInstruction;
import com.ibm.wala.ssa.SSAInvokeInstruction;
import com.ibm.wala.ssa.SSALoadIndirectInstruction;
import com.ibm.wala.ssa.SSALoadMetadataInstruction;
import com.ibm.wala.ssa.SSAMonitorInstruction;
import com.ibm.wala.ssa.SSANewInstruction;
import com.ibm.wala.ssa.SSAPhiInstruction;
import com.ibm.wala.ssa.SSAPiInstruction;
import com.ibm.wala.ssa.SSAPutInstruction;
import com.ibm.wala.ssa.SSAReturnInstruction;
import com.ibm.wala.ssa.SSAStoreIndirectInstruction;
import com.ibm.wala.ssa.SSASwitchInstruction;
import com.ibm.wala.ssa.SSAThrowInstruction;
import com.ibm.wala.ssa.SSAUnaryOpInstruction;
import com.ibm.wala.types.ClassLoaderReference;
import com.ibm.wala.types.Descriptor;
import com.ibm.wala.types.FieldReference;
import com.ibm.wala.types.MethodReference;
import com.ibm.wala.types.Selector;
import com.ibm.wala.types.TypeName;
import com.ibm.wala.types.TypeReference;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;

/** The implementation of {@link Language} which defines Java semantics. */
public class JavaLanguage extends LanguageImpl implements BytecodeLanguage, Constants {

  public static class JavaInstructionFactory implements SSAInstructionFactory {
    @Override
    public SSAArrayLengthInstruction ArrayLengthInstruction(int iindex, int result, int arrayref) {
      return new SSAArrayLengthInstruction(iindex, result, arrayref) {
        @Override
        public Collection getExceptionTypes() {
          return getNullPointerException();
        }
      };
    }

    @Override
    public SSAArrayLoadInstruction ArrayLoadInstruction(
        int iindex, int result, int arrayref, int index, TypeReference declaredType) {
      return new SSAArrayLoadInstruction(iindex, result, arrayref, index, declaredType) {
        @Override
        public Collection getExceptionTypes() {
          return getArrayAccessExceptions();
        }
      };
    }

    @Override
    public SSAArrayStoreInstruction ArrayStoreInstruction(
        int iindex, int arrayref, int index, int value, TypeReference declaredType) {
      return new SSAArrayStoreInstruction(iindex, arrayref, index, value, declaredType) {
        @Override
        public Collection getExceptionTypes() {
          if (typeIsPrimitive()) {
            return getArrayAccessExceptions();
          } else {
            return getAaStoreExceptions();
          }
        }
      };
    }

    @Override
    public SSAAbstractBinaryInstruction BinaryOpInstruction(
        int iindex,
        IBinaryOpInstruction.IOperator operator,
        boolean overflow,
        boolean unsigned,
        int result,
        int val1,
        int val2,
        boolean mayBeInteger) {
      assert !overflow;
      // assert (!unsigned) : "BinaryOpInstuction: unsigned disallowed! iIndex: " + iindex + ",
      // operation: " + val1 + " " + operator.toString() + " " + val2 ;
      return new SSABinaryOpInstruction(iindex, operator, result, val1, val2, mayBeInteger) {

        @Override
        public SSAInstruction copyForSSA(SSAInstructionFactory insts, int[] defs, int[] uses) {
          return insts.BinaryOpInstruction(
              iIndex(),
              getOperator(),
              false,
              false,
              defs == null || defs.length == 0 ? getDef(0) : defs[0],
              uses == null ? getUse(0) : uses[0],
              uses == null ? getUse(1) : uses[1],
              mayBeIntegerOp());
        }

        @Override
        public Collection getExceptionTypes() {
          if (isPEI()) {
            return getArithmeticException();
          } else {
            return Collections.emptySet();
          }
        }
      };
    }

    @Override
    public SSACheckCastInstruction CheckCastInstruction(
        int iindex, int result, int val, int[] typeValues, boolean isPEI) {
      throw new UnsupportedOperationException();
    }

    @Override
    public SSACheckCastInstruction CheckCastInstruction(
        int iindex, int result, int val, TypeReference[] types, boolean isPEI) {
      assert types.length == 1;
      assert isPEI;
      return new SSACheckCastInstruction(iindex, result, val, types, true) {
        @Override
        public Collection getExceptionTypes() {
          return getClassCastException();
        }
      };
    }

    @Override
    public SSACheckCastInstruction CheckCastInstruction(
        int iindex, int result, int val, int typeValue, boolean isPEI) {
      assert isPEI;
      return CheckCastInstruction(iindex, result, val, new int[] {typeValue}, true);
    }

    @Override
    public SSACheckCastInstruction CheckCastInstruction(
        int iindex, int result, int val, TypeReference type, boolean isPEI) {
      assert isPEI;
      return CheckCastInstruction(iindex, result, val, new TypeReference[] {type}, true);
    }

    @Override
    public SSAComparisonInstruction ComparisonInstruction(
        int iindex, IComparisonInstruction.Operator operator, int result, int val1, int val2) {
      return new SSAComparisonInstruction(iindex, operator, result, val1, val2);
    }

    @Override
    public SSAConditionalBranchInstruction ConditionalBranchInstruction(
        int iindex,
        IConditionalBranchInstruction.IOperator operator,
        TypeReference type,
        int val1,
        int val2,
        int target) {
      return new SSAConditionalBranchInstruction(iindex, operator, type, val1, val2, target);
    }

    @Override
    public SSAConversionInstruction ConversionInstruction(
        int iindex,
        int result,
        int val,
        TypeReference fromType,
        TypeReference toType,
        boolean overflow) {
      assert !overflow;
      return new SSAConversionInstruction(iindex, result, val, fromType, toType) {
        @Override
        public SSAInstruction copyForSSA(SSAInstructionFactory insts, int[] defs, int[] uses)
            throws IllegalArgumentException {
          if (uses != null && uses.length == 0) {
            throw new IllegalArgumentException("(uses != null) and (uses.length == 0)");
          }
          return insts.ConversionInstruction(
              iIndex(),
              defs == null || defs.length == 0 ? getDef(0) : defs[0],
              uses == null ? getUse(0) : uses[0],
              getFromType(),
              getToType(),
              false);
        }
      };
    }

    @Override
    public SSAGetCaughtExceptionInstruction GetCaughtExceptionInstruction(
        int iindex, int bbNumber, int exceptionValueNumber) {
      return new SSAGetCaughtExceptionInstruction(iindex, bbNumber, exceptionValueNumber);
    }

    @Override
    public SSAGetInstruction GetInstruction(int iindex, int result, FieldReference field) {
      return new SSAGetInstruction(iindex, result, field) {};
    }

    @Override
    public SSAGetInstruction GetInstruction(int iindex, int result, int ref, FieldReference field) {
      return new SSAGetInstruction(iindex, result, ref, field) {
        @Override
        public Collection getExceptionTypes() {
          return getNullPointerException();
        }
      };
    }

    @Override
    public SSAGotoInstruction GotoInstruction(int iindex, int target) {
      return new SSAGotoInstruction(iindex, target);
    }

    @Override
    public SSAInstanceofInstruction InstanceofInstruction(
        int iindex, int result, int ref, TypeReference checkedType) {
      return new SSAInstanceofInstruction(iindex, result, ref, checkedType);
    }

    @Override
    public SSAAbstractInvokeInstruction InvokeInstruction(
        int iindex,
        int result,
        int[] params,
        int exception,
        CallSiteReference site,
        BootstrapMethod bootstrap) {
      if (bootstrap != null) {
        return new SSAInvokeDynamicInstruction(iindex, result, params, exception, site, bootstrap) {
          @Override
          public Collection getExceptionTypes() {
            if (!isStatic()) {
              return getNullPointerException();
            } else {
              return Collections.emptySet();
            }
          }
        };
      } else {
        return new SSAInvokeInstruction(iindex, result, params, exception, site) {
          @Override
          public Collection getExceptionTypes() {
            if (!isStatic()) {
              return getNullPointerException();
            } else {
              return Collections.emptySet();
            }
          }
        };
      }
    }

    @Override
    public SSAAbstractInvokeInstruction InvokeInstruction(
        int iindex,
        int[] params,
        int exception,
        CallSiteReference site,
        BootstrapMethod bootstrap) {
      // -1 is used to represent no result
      return InvokeInstruction(iindex, -1, params, exception, site, bootstrap);
    }

    @Override
    public SSAMonitorInstruction MonitorInstruction(int iindex, int ref, boolean isEnter) {
      return new SSAMonitorInstruction(iindex, ref, isEnter) {
        @Override
        public Collection getExceptionTypes() {
          return getNullPointerException();
        }
      };
    }

    @Override
    public SSANewInstruction NewInstruction(int iindex, int result, NewSiteReference site) {
      return new SSANewInstruction(iindex, result, site) {
        @Override
        public Collection getExceptionTypes() {
          if (getNewSite().getDeclaredType().isArrayType()) {
            return getNewArrayExceptions();
          } else {
            return getNewScalarExceptions();
          }
        }
      };
    }

    @Override
    public SSAPhiInstruction PhiInstruction(int iindex, int result, int[] params)
        throws IllegalArgumentException {
      return new SSAPhiInstruction(iindex, result, params) {};
    }

    @Override
    public SSAPutInstruction PutInstruction(int iindex, int ref, int value, FieldReference field) {
      return new SSAPutInstruction(iindex, ref, value, field) {
        @Override
        public Collection getExceptionTypes() {
          return getNullPointerException();
        }
      };
    }

    @Override
    public SSAPutInstruction PutInstruction(int iindex, int value, FieldReference field) {
      return new SSAPutInstruction(iindex, value, field) {};
    }

    @Override
    public SSAReturnInstruction ReturnInstruction(int iindex) {
      return new SSAReturnInstruction(iindex);
    }

    @Override
    public SSAReturnInstruction ReturnInstruction(int iindex, int result, boolean isPrimitive) {
      return new SSAReturnInstruction(iindex, result, isPrimitive);
    }

    @Override
    public SSASwitchInstruction SwitchInstruction(
        int iindex, int val, int defaultLabel, int[] casesAndLabels) {
      return new SSASwitchInstruction(iindex, val, defaultLabel, casesAndLabels);
    }

    @Override
    public SSAThrowInstruction ThrowInstruction(int iindex, int exception) {
      return new SSAThrowInstruction(iindex, exception) {
        @Override
        public Collection getExceptionTypes() {
          return getNullPointerException();
        }
      };
    }

    @Override
    public SSAUnaryOpInstruction UnaryOpInstruction(
        int iindex, IUnaryOpInstruction.IOperator operator, int result, int val) {
      return new SSAUnaryOpInstruction(iindex, operator, result, val);
    }

    @Override
    public SSALoadMetadataInstruction LoadMetadataInstruction(
        int iindex, int lval, TypeReference entityType, Object token) {
      return new SSALoadMetadataInstruction(iindex, lval, entityType, token) {
        @Override
        public Collection getExceptionTypes() {
          return loadClassExceptions;
        }
      };
    }

    @Override
    public SSANewInstruction NewInstruction(
        int iindex, int result, NewSiteReference site, int[] params) {
      return new SSANewInstruction(iindex, result, site, params) {
        @Override
        public Collection getExceptionTypes() {
          return getNewArrayExceptions();
        }
      };
    }

    @Override
    public SSAPiInstruction PiInstruction(
        int iindex, int result, int val, int piBlock, int successorBlock, SSAInstruction cause) {
      return new SSAPiInstruction(iindex, result, val, piBlock, successorBlock, cause);
    }

    @Override
    public SSAAddressOfInstruction AddressOfInstruction(
        int iindex, int lval, int local, TypeReference pointeeType) {
      throw new UnsupportedOperationException();
    }

    @Override
    public SSAAddressOfInstruction AddressOfInstruction(
        int iindex, int lval, int local, int indexVal, TypeReference pointeeType) {
      throw new UnsupportedOperationException();
    }

    @Override
    public SSAAddressOfInstruction AddressOfInstruction(
        int iindex, int lval, int local, FieldReference field, TypeReference pointeeType) {
      throw new UnsupportedOperationException();
    }

    @Override
    public SSALoadIndirectInstruction LoadIndirectInstruction(
        int iindex, int lval, TypeReference t, int addressVal) {
      throw new UnsupportedOperationException();
    }

    @Override
    public SSAStoreIndirectInstruction StoreIndirectInstruction(
        int iindex, int addressVal, int rval, TypeReference pointeeType) {
      throw new UnsupportedOperationException();
    }
  }

  private static final Collection arrayAccessExceptions =
      Collections.unmodifiableCollection(
          Arrays.asList(
              new TypeReference[] {
                TypeReference.JavaLangNullPointerException,
                TypeReference.JavaLangArrayIndexOutOfBoundsException
              }));

  private static final Collection aaStoreExceptions =
      Collections.unmodifiableCollection(
          Arrays.asList(
              new TypeReference[] {
                TypeReference.JavaLangNullPointerException,
                TypeReference.JavaLangArrayIndexOutOfBoundsException,
                TypeReference.JavaLangArrayStoreException
              }));

  private static final Collection newScalarExceptions =
      Collections.unmodifiableCollection(
          Arrays.asList(
              new TypeReference[] {
                TypeReference.JavaLangExceptionInInitializerError,
                TypeReference.JavaLangOutOfMemoryError
              }));

  private static final Collection newArrayExceptions =
      Collections.unmodifiableCollection(
          Arrays.asList(
              new TypeReference[] {
                TypeReference.JavaLangOutOfMemoryError,
                TypeReference.JavaLangNegativeArraySizeException
              }));

  private static final Collection newSafeArrayExceptions =
      Collections.unmodifiableCollection(
          Arrays.asList(new TypeReference[] {TypeReference.JavaLangOutOfMemoryError}));

  private static final Collection exceptionInInitializerError =
      Collections.singleton(TypeReference.JavaLangExceptionInInitializerError);

  private static final Collection nullPointerException =
      Collections.singleton(TypeReference.JavaLangNullPointerException);

  private static final Collection arithmeticException =
      Collections.singleton(TypeReference.JavaLangArithmeticException);

  private static final Collection classCastException =
      Collections.singleton(TypeReference.JavaLangClassCastException);

  private static final Collection classNotFoundException =
      Collections.singleton(TypeReference.JavaLangClassNotFoundException);

  private static final Collection loadClassExceptions =
      Collections.singleton(TypeReference.JavaLangClassNotFoundException);

  public static Collection getAaStoreExceptions() {
    return aaStoreExceptions;
  }

  public static Collection getArithmeticException() {
    return arithmeticException;
  }

  public static Collection getArrayAccessExceptions() {
    return arrayAccessExceptions;
  }

  public static Collection getClassCastException() {
    return classCastException;
  }

  public static Collection getClassNotFoundException() {
    return classNotFoundException;
  }

  public static Collection getNewArrayExceptions() {
    return newArrayExceptions;
  }

  public static Collection getNewSafeArrayExceptions() {
    return newSafeArrayExceptions;
  }

  public static Collection getNewScalarExceptions() {
    return newScalarExceptions;
  }

  public static Collection getNullPointerException() {
    return nullPointerException;
  }

  public static Collection getExceptionInInitializerError() {
    return exceptionInInitializerError;
  }

  @Override
  public Atom getName() {
    return ClassLoaderReference.Java;
  }

  @Override
  public TypeReference getRootType() {
    return TypeReference.JavaLangObject;
  }

  @Override
  public TypeReference getThrowableType() {
    return TypeReference.JavaLangThrowable;
  }

  @Override
  public TypeReference getConstantType(Object o) {
    if (o == null) {
      // TODO: do we really want null here instead of TypeReference.Null?
      // lots of code seems to depend on this being null.
      return null;
    } else if (o instanceof Boolean) {
      return TypeReference.Boolean;
    } else if (o instanceof Long) {
      return TypeReference.Long;
    } else if (o instanceof Double) {
      return TypeReference.Double;
    } else if (o instanceof Float) {
      return TypeReference.Float;
    } else if (o instanceof Number) {
      return TypeReference.Int;
    } else if (o instanceof String) {
      return TypeReference.JavaLangString;
    } else if (o instanceof ClassToken || o instanceof TypeReference) {
      return TypeReference.JavaLangClass;
    } else if (o instanceof IMethod) {
      IMethod m = (IMethod) o;
      return m.isInit()
          ? TypeReference.JavaLangReflectConstructor
          : TypeReference.JavaLangReflectMethod;
    } else if (o instanceof MethodHandle || o instanceof ReferenceToken) {
      return TypeReference.JavaLangInvokeMethodHandle;
    } else if (o instanceof MethodType) {
      return TypeReference.JavaLangInvokeMethodType;
    } else {
      assert false : "unknown constant " + o + ": " + o.getClass();
      return null;
    }
  }

  @Override
  public boolean isNullType(TypeReference type) {
    return type == null || type == TypeReference.Null;
  }

  @Override
  public TypeReference[] getArrayInterfaces() {
    return new TypeReference[] {TypeReference.JavaIoSerializable, TypeReference.JavaLangCloneable};
  }

  @Override
  public TypeName lookupPrimitiveType(String name) {
    throw new UnsupportedOperationException();
  }

  /**
   * @return {@link Collection}<{@link TypeReference}>, set of exception types a call to a
   *     declared target might throw.
   * @throws IllegalArgumentException if target is null
   * @throws IllegalArgumentException if cha is null
   */
  @Override
  public Collection inferInvokeExceptions(
      MethodReference target, IClassHierarchy cha) throws InvalidClassFileException {

    if (cha == null) {
      throw new IllegalArgumentException("cha is null");
    }
    if (target == null) {
      throw new IllegalArgumentException("target is null");
    }
    ArrayList set = new ArrayList<>(cha.getJavaLangRuntimeExceptionTypes());
    set.addAll(cha.getJavaLangErrorTypes());

    IClass klass = cha.lookupClass(target.getDeclaringClass());
    if (klass == null) {
      Warnings.add(MethodResolutionFailure.moderate(target));
    }
    if (klass != null) {
      IMethod M = klass.getMethod(target.getSelector());
      if (M == null) {
        Warnings.add(MethodResolutionFailure.severe(target));
      } else {
        TypeReference[] exceptionTypes = M.getDeclaredExceptions();
        if (exceptionTypes != null) {
          set.addAll(Arrays.asList(exceptionTypes));
        }
      }
    }
    return set;
  }

  /**
   * @param pei a potentially-excepting instruction
   * @return the exception types that pei may throw, independent of the class hierarchy. null if
   *     none.
   *     

Notes *

    *
  • this method will NOT return the exception type explicitly thrown by an * athrow *
  • this method will NOT return the exception types that a called method may * throw *
  • this method ignores OutOfMemoryError *
  • this method ignores linkage errors *
  • this method ignores IllegalMonitorState exceptions *
* * @throws IllegalArgumentException if pei is null */ @Override public Collection getImplicitExceptionTypes(IInstruction pei) { if (pei == null) { throw new IllegalArgumentException("pei is null"); } switch (((Instruction) pei).getOpcode()) { case OP_iaload: case OP_laload: case OP_faload: case OP_daload: case OP_aaload: case OP_baload: case OP_caload: case OP_saload: case OP_iastore: case OP_lastore: case OP_fastore: case OP_dastore: case OP_bastore: case OP_castore: case OP_sastore: return getArrayAccessExceptions(); case OP_aastore: return getAaStoreExceptions(); case OP_getfield: case OP_putfield: case OP_invokevirtual: case OP_invokespecial: case OP_invokeinterface: case OP_monitorenter: case OP_monitorexit: // we're currently ignoring MonitorStateExceptions, since J2EE stuff // should be // logically single-threaded case OP_athrow: // N.B: the caller must handle the explicitly-thrown exception case OP_arraylength: return getNullPointerException(); case OP_idiv: case OP_irem: case OP_ldiv: case OP_lrem: return getArithmeticException(); case OP_new: return newScalarExceptions; case OP_newarray: case OP_anewarray: case OP_multianewarray: return newArrayExceptions; case OP_checkcast: return getClassCastException(); case OP_ldc_w: if (((ConstantInstruction) pei).getType().equals(TYPE_Class)) return getClassNotFoundException(); else return null; case OP_getstatic: case OP_putstatic: return getExceptionInInitializerError(); default: return Collections.emptySet(); } } @Override public SSAInstructionFactory instructionFactory() { return javaShrikeFactory; } private static final SSAInstructionFactory javaShrikeFactory = new JavaInstructionFactory(); @Override public boolean isDoubleType(TypeReference type) { return type == TypeReference.Double; } @Override public boolean isFloatType(TypeReference type) { return type == TypeReference.Float; } @Override public boolean isIntType(TypeReference type) { return type == TypeReference.Int; } @Override public boolean isLongType(TypeReference type) { return type == TypeReference.Long; } @Override public boolean isVoidType(TypeReference type) { return type == TypeReference.Void; } @Override public boolean isMetadataType(TypeReference type) { return type == TypeReference.JavaLangClass || type == TypeReference.JavaLangInvokeMethodHandle || type == TypeReference.JavaLangInvokeMethodType; } @Override public boolean isStringType(TypeReference type) { return type == TypeReference.JavaLangString; } @Override public boolean isBooleanType(TypeReference type) { return type == TypeReference.Boolean; } @Override public boolean isCharType(TypeReference type) { return type == TypeReference.Char; } @Override public Object getMetadataToken(Object value) { if (value instanceof ClassToken) { return ShrikeUtil.makeTypeReference( ClassLoaderReference.Application, ((ClassToken) value).getTypeName()); } else if (value instanceof ReferenceToken) { ReferenceToken tok = (ReferenceToken) value; TypeReference cls = ShrikeUtil.makeTypeReference(ClassLoaderReference.Application, 'L' + tok.getClassName()); return MethodReference.findOrCreate( cls, new Selector( Atom.findOrCreateUnicodeAtom(tok.getElementName()), Descriptor.findOrCreateUTF8(tok.getDescriptor()))); } else if (value instanceof MethodHandle || value instanceof MethodType) { return value; } else { assert value instanceof TypeReference; return value; } } @Override public TypeReference getPointerType(TypeReference pointee) throws UnsupportedOperationException { throw new UnsupportedOperationException("Java does not permit explicit pointers"); } @Override public TypeReference getStringType() { return TypeReference.JavaLangString; } static { JavaPrimitiveType.init(); } @Override @SuppressWarnings("static-access") public PrimitiveType getPrimitive(TypeReference reference) { return JavaPrimitiveType.getPrimitive(reference); } @Override public MethodReference getInvokeMethodReference( ClassLoaderReference loader, IInvokeInstruction instruction) { return MethodReference.findOrCreate( this, loader, instruction.getClassType(), instruction.getMethodName(), instruction.getMethodSignature()); } @Override public boolean methodsHaveDeclaredParameterTypes() { return true; } @Override public AbstractRootMethod getFakeRootMethod( IClassHierarchy cha, AnalysisOptions options, IAnalysisCacheView cache) { return new FakeRootMethod( new FakeRootClass(ClassLoaderReference.Primordial, cha), options, cache); } @Override public RefVisitor makeRefVisitor( CGNode n, Collection result, PointerAnalysis pa, ExtendedHeapModel h) { return new RefVisitor<>(n, result, pa, h); } @Override public ModVisitor makeModVisitor( CGNode n, Collection result, PointerAnalysis pa, ExtendedHeapModel h, boolean ignoreAllocHeapDefs) { return new ModVisitor<>(n, result, h, pa, ignoreAllocHeapDefs); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy