/**
  * @param m a method reference
  * @return a SyntheticMethod corresponding to m; or null if none is available.
  */
 protected SyntheticMethod findOrCreateSyntheticMethod(MethodReference m, boolean isStatic) {
   if (syntheticMethods.containsKey(m)) {
     return syntheticMethods.get(m);
   } else {
     MethodSummary summ = null;
     if (canIgnore(m)) {
       TypeReference T = m.getDeclaringClass();
       IClass C = cha.lookupClass(T);
       if (C == null) {
         // did not load class; don't try to create a synthetic method
         syntheticMethods.put(m, null);
         return null;
       }
       summ = generateNoOp(m, isStatic);
     } else {
       summ = findSummary(m);
     }
     if (summ != null) {
       TypeReference T = m.getDeclaringClass();
       IClass C = cha.lookupClass(T);
       if (C == null) {
         syntheticMethods.put(m, null);
         return null;
       }
       SummarizedMethod n = new SummarizedMethod(m, summ, C);
       syntheticMethods.put(m, n);
       return n;
     } else {
       syntheticMethods.put(m, null);
       return null;
     }
   }
 }
Beispiel #2
0
  @Test
  public void testClassAnnotations3() throws Exception {

    TypeReference typeRef =
        TypeReference.findOrCreate(
            ClassLoaderReference.Application, "Lannotations/AnnotatedClass3");
    IClass klass = cha.lookupClass(typeRef);
    Assert.assertNotNull(klass);
    ShrikeClass shrikeClass = (ShrikeClass) klass;
    Collection<Annotation> classAnnotations = shrikeClass.getAnnotations(true);
    Assert.assertEquals(
        "[Annotation type <Application,Lannotations/AnnotationWithParams> {strParam=classStrParam}]",
        classAnnotations.toString());

    MethodReference methodRefUnderTest =
        MethodReference.findOrCreate(typeRef, Selector.make("foo()V"));

    IMethod methodUnderTest = cha.resolveMethod(methodRefUnderTest);
    Assert.assertNotNull(methodRefUnderTest.toString() + " not found", methodUnderTest);
    Assert.assertTrue(methodUnderTest instanceof ShrikeCTMethod);
    ShrikeCTMethod shrikeCTMethodUnderTest = (ShrikeCTMethod) methodUnderTest;

    Collection<Annotation> runtimeInvisibleAnnotations =
        shrikeCTMethodUnderTest.getAnnotations(true);
    Assert.assertEquals(
        "[Annotation type <Application,Lannotations/AnnotationWithParams> {enumParam=EnumElementValue [type=Lannotations/AnnotationEnum;, val=VAL1], strArrParam=ArrayElementValue [vals=[biz, boz]], annotParam=AnnotationElementValue [type=Lannotations/AnnotationWithSingleParam;, elementValues={value=sdfevs}], strParam=sdfsevs, intParam=25, klassParam=Ljava/lang/Integer;}]",
        runtimeInvisibleAnnotations.toString());
  }
  /** check that the types of all instance keys are assignable to declared type of pointer key */
  private void checkTypes(IntSet b) {
    assert PARANOID;
    if (b == null) return;
    if (!(pointerKey instanceof LocalPointerKey)) {
      return;
    }
    final LocalPointerKey lpk = (LocalPointerKey) pointerKey;
    CGNode node = lpk.getNode();
    final IClassHierarchy cha = node.getClassHierarchy();
    final IR ir = node.getIR();
    if (ir == null) return;
    TypeInference ti = TypeInference.make(ir, false);
    final IClass type = ti.getType(lpk.getValueNumber()).getType();
    if (type == null) return;
    // don't perform checking for exception variables
    if (cha.isAssignableFrom(cha.lookupClass(TypeReference.JavaLangThrowable), type)) {
      return;
    }
    b.foreach(
        new IntSetAction() {

          public void act(int x) {
            InstanceKey ik = instanceKeys.getMappedObject(x);
            IClass concreteType = ik.getConcreteType();
            if (!cha.isAssignableFrom(type, concreteType)) {
              System.err.println("BOOM");
              System.err.println(ir);
              System.err.println(lpk + " type " + type);
              System.err.println(ik + " type " + concreteType);
              Assertions.UNREACHABLE();
            }
          }
        });
  }
 /**
  * @param type
  * @return a TypeAbstraction object representing this type. We just use ConeTypes by default,
  *     since we don't propagate information allowing us to distinguish between points and cones
  *     yet.
  */
 protected TypeAbstraction typeRef2TypeAbstraction(IClassHierarchy cha, TypeReference type) {
   IClass klass = cha.lookupClass(type);
   if (klass != null) {
     return new ConeType(klass);
   }
   Assertions.UNREACHABLE(type.toString());
   return null;
 }
 /**
  * @param method
  * @return the receiver class for this method.
  */
 private IClass getReceiverClass(IMethod method) {
   TypeReference formalType = method.getParameterType(0);
   IClass C = cha.lookupClass(formalType);
   if (method.isStatic()) {
     Assertions.UNREACHABLE("asked for receiver of static method " + method);
   }
   if (C == null) {
     Assertions.UNREACHABLE("no class found for " + formalType + " recv of " + method);
   }
   return C;
 }
 @Override
 public IMethod getCalleeTarget(CGNode caller, CallSiteReference site, IClass receiver) {
   if (site.getDeclaredTarget().equals(JavaScriptMethods.ctorReference)) {
     assert cha.isSubclassOf(receiver, cha.lookupClass(JavaScriptTypes.Root));
     IR callerIR = caller.getIR();
     SSAAbstractInvokeInstruction callStmts[] = callerIR.getCalls(site);
     assert callStmts.length == 1;
     int nargs = callStmts[0].getNumberOfParameters();
     return findOrCreateConstructorMethod(callerIR, callStmts[0], receiver, nargs - 1);
   } else {
     return base.getCalleeTarget(caller, site, receiver);
   }
 }
 /** @return Map: IClass -> Integer, the number of allocation sites for each type. */
 private Map<IClass, Integer> countAllocsByType(CGNode node) {
   Map<IClass, Integer> count = HashMapFactory.make();
   for (Iterator it = contextInterpreter.iterateNewSites(node); it.hasNext(); ) {
     NewSiteReference n = (NewSiteReference) it.next();
     IClass alloc = cha.lookupClass(n.getDeclaredType());
     if (alloc != null) {
       Integer old = count.get(alloc);
       if (old == null) {
         count.put(alloc, new Integer(1));
       } else {
         count.put(alloc, new Integer(old.intValue() + 1));
       }
     }
   }
   return count;
 }
Beispiel #8
0
  private void testClassAnnotations(
      TypeReference typeUnderTest,
      Collection<Annotation> expectedRuntimeInvisibleAnnotations,
      Collection<Annotation> expectedRuntimeVisibleAnnotations)
      throws IOException, ClassHierarchyException, InvalidClassFileException {
    IClass classUnderTest = cha.lookupClass(typeUnderTest);
    Assert.assertNotNull(typeUnderTest.toString() + " not found", classUnderTest);
    Assert.assertTrue(classUnderTest instanceof ShrikeClass);
    ShrikeClass shrikeClassUnderTest = (ShrikeClass) classUnderTest;

    Collection<Annotation> runtimeInvisibleAnnotations =
        shrikeClassUnderTest.getRuntimeInvisibleAnnotations();
    assertEqualCollections(expectedRuntimeInvisibleAnnotations, runtimeInvisibleAnnotations);

    Collection<Annotation> runtimeVisibleAnnotations =
        shrikeClassUnderTest.getRuntimeVisibleAnnotations();
    assertEqualCollections(expectedRuntimeVisibleAnnotations, runtimeVisibleAnnotations);
  }
 private IMethod findOrCreateConstructorMethod(
     IR callerIR, SSAAbstractInvokeInstruction callStmt, IClass receiver, int nargs) {
   if (receiver.getReference().equals(JavaScriptTypes.Object))
     return makeObjectConstructor(receiver, nargs);
   else if (receiver.getReference().equals(JavaScriptTypes.Array))
     return makeArrayConstructor(receiver, nargs);
   else if (receiver.getReference().equals(JavaScriptTypes.StringObject))
     return makeValueConstructor(receiver, nargs, "");
   else if (receiver.getReference().equals(JavaScriptTypes.BooleanObject)) {
     assert nargs == 1;
     return makeValueConstructor(receiver, nargs, null);
   } else if (receiver.getReference().equals(JavaScriptTypes.NumberObject))
     return makeValueConstructor(receiver, nargs, new Integer(0));
   else if (receiver.getReference().equals(JavaScriptTypes.Function))
     return makeFunctionConstructor(callerIR, callStmt, receiver, nargs);
   else if (cha.isSubclassOf(receiver, cha.lookupClass(JavaScriptTypes.CodeBody)))
     return makeFunctionObjectConstructor(receiver, nargs);
   else {
     return null;
   }
 }
  public InstanceKey getInstanceKeyForAllocation(CGNode node, NewSiteReference allocation) {
    if (allocation == null) {
      throw new IllegalArgumentException("allocation is null");
    }
    TypeReference t = allocation.getDeclaredType();
    IClass C = cha.lookupClass(t);

    if (C != null && isInteresting(C)) {
      if (smushMany()) {
        if (exceedsSmushLimit(C, node)) {
          return smushed.getInstanceKeyForAllocation(node, allocation);
        } else {
          return siteBased.getInstanceKeyForAllocation(node, allocation);
        }
      } else {
        return siteBased.getInstanceKeyForAllocation(node, allocation);
      }
    } else {
      return classBased.getInstanceKeyForAllocation(node, allocation);
    }
  }
Beispiel #11
0
    /**
     * Add any exceptional edges generated by the last instruction in a basic block.
     *
     * @param last the last instruction in a basic block.
     */
    protected void addExceptionalEdges(IInstruction last) {
      IClassHierarchy cha = getMethod().getClassHierarchy();
      if (last.isPEI()) {
        Collection<TypeReference> exceptionTypes = null;
        boolean goToAllHandlers = false;

        ExceptionHandler[] hs = getExceptionHandlers();
        if (last instanceof ThrowInstruction) {
          // this class does not have the type information needed
          // to determine what the athrow throws. So, add an
          // edge to all reachable handlers. Better information can
          // be obtained later with SSA type propagation.
          // TODO: consider pruning to only the exception types that
          // this method either catches or allocates, since these are
          // the only types that can flow to an athrow.
          goToAllHandlers = true;
        } else {
          if (hs != null && hs.length > 0) {
            IClassLoader loader = getMethod().getDeclaringClass().getClassLoader();
            BytecodeLanguage l = (BytecodeLanguage) loader.getLanguage();
            exceptionTypes = l.getImplicitExceptionTypes(last);
            if (last instanceof IInvokeInstruction) {
              IInvokeInstruction call = (IInvokeInstruction) last;
              exceptionTypes = HashSetFactory.make(exceptionTypes);
              MethodReference target =
                  MethodReference.findOrCreate(
                      l,
                      loader.getReference(),
                      call.getClassType(),
                      call.getMethodName(),
                      call.getMethodSignature());
              try {
                exceptionTypes.addAll(l.inferInvokeExceptions(target, cha));
              } catch (InvalidClassFileException e) {
                e.printStackTrace();
                Assertions.UNREACHABLE();
              }
            }
          }
        }

        if (hs != null && hs.length > 0) {
          // found a handler for this PEI

          // create a mutable copy
          if (!goToAllHandlers) {
            exceptionTypes = HashSetFactory.make(exceptionTypes);
          }

          // this var gets set to false if goToAllHandlers is true but some enclosing exception
          // handler catches all
          // exceptions.  in such a case, we need not add an exceptional edge to the method exit
          boolean needEdgeToExitForAllHandlers = true;
          for (int j = 0; j < hs.length; j++) {
            if (DEBUG) {
              System.err.println(" handler " + hs[j]);
            }
            BasicBlock b = getBlockForInstruction(hs[j].getHandler());
            if (DEBUG) {
              System.err.println(" target " + b);
            }
            if (goToAllHandlers) {
              // add an edge to the catch block.
              if (DEBUG) {
                System.err.println(" gotoAllHandlers " + b);
              }
              addExceptionalEdgeTo(b);
              // if the handler catches all exceptions, we don't need to add an edge to the exit or
              // any other handlers
              if (hs[j].getCatchClass() == null) {
                needEdgeToExitForAllHandlers = false;
                break;
              }
            } else {
              TypeReference caughtException = null;
              if (hs[j].getCatchClass() != null) {
                ClassLoaderReference loader =
                    ShrikeCFG.this.getMethod().getDeclaringClass().getReference().getClassLoader();
                caughtException = ShrikeUtil.makeTypeReference(loader, hs[j].getCatchClass());
                if (DEBUG) {
                  System.err.println(" caughtException " + caughtException);
                }
                IClass caughtClass = cha.lookupClass(caughtException);
                if (caughtClass == null) {
                  // conservatively add the edge, and raise a warning
                  addExceptionalEdgeTo(b);
                  Warnings.add(FailedExceptionResolutionWarning.create(caughtException));
                  // null out caughtException, to avoid attempting to process it
                  caughtException = null;
                }
              } else {
                if (DEBUG) {
                  System.err.println(" catchClass() == null");
                }
                // hs[j].getCatchClass() == null.
                // this means that the handler catches all exceptions.
                // add the edge and null out all types
                if (!exceptionTypes.isEmpty()) {
                  addExceptionalEdgeTo(b);
                  exceptionTypes.clear();
                  caughtException = null;
                }
              }
              if (caughtException != null) {
                IClass caughtClass = cha.lookupClass(caughtException);
                // the set "caught" should be the set of exceptions that MUST
                // have been caught by the handlers in scope
                ArrayList<TypeReference> caught =
                    new ArrayList<TypeReference>(exceptionTypes.size());
                // check if we should add an edge to the catch block.
                for (TypeReference t : exceptionTypes) {
                  if (t != null) {
                    IClass klass = cha.lookupClass(t);
                    if (klass == null) {
                      Warnings.add(FailedExceptionResolutionWarning.create(caughtException));
                      // conservatively add an edge
                      addExceptionalEdgeTo(b);
                    } else {
                      boolean subtype1 = cha.isSubclassOf(klass, caughtClass);
                      if (subtype1 || cha.isSubclassOf(caughtClass, klass)) {
                        // add the edge and null out the type from the array
                        addExceptionalEdgeTo(b);
                        if (subtype1) {
                          caught.add(t);
                        }
                      }
                    }
                  }
                }
                exceptionTypes.removeAll(caught);
              }
            }
          }
          // if needed, add an edge to the exit block.
          if ((exceptionTypes == null && needEdgeToExitForAllHandlers)
              || (exceptionTypes != null && !exceptionTypes.isEmpty())) {
            BasicBlock exit = exit();
            addExceptionalEdgeTo(exit);
          }
        } else {
          // found no handler for this PEI ... link to the exit block.
          BasicBlock exit = exit();
          addExceptionalEdgeTo(exit);
        }
      }
    }
Beispiel #12
0
 /*
  * @see com.ibm.wala.classLoader.IClass#getMethod(com.ibm.wala.classLoader.Selector)
  */
 @Override
 public IMethod getMethod(Selector sig) {
   return cha.lookupClass(getClassLoader().getLanguage().getRootType()).getMethod(sig);
 }
  private IMethod makeFunctionConstructor(
      IR callerIR, SSAAbstractInvokeInstruction callStmt, IClass cls, int nargs) {
    SymbolTable ST = callerIR.getSymbolTable();

    if (nargs == 0) {
      return makeFunctionConstructor(cls, cls);
    } else if (nargs == 1) {
      if (ST.isStringConstant(callStmt.getUse(1))) {
        TypeReference ref =
            TypeReference.findOrCreate(
                JavaScriptTypes.jsLoader,
                TypeName.string2TypeName((String) ST.getStringValue(callStmt.getUse(1))));

        if (DEBUG) {
          System.err.println(
              ("ctor type name is " + (String) ST.getStringValue(callStmt.getUse(1))));
        }

        IClass cls2 = cha.lookupClass(ref);
        if (cls2 != null) {
          return makeFunctionConstructor(cls, cls2);
        }
      }

      return makeFunctionConstructor(cls, cls);
    } else {
      assert nargs > 1;
      JavaScriptLoader cl = (JavaScriptLoader) cha.getLoader(JavaScriptTypes.jsLoader);

      for (int i = 1; i < callStmt.getNumberOfUses(); i++)
        if (!ST.isStringConstant(callStmt.getUse(i))) return makeFunctionConstructor(cls, cls);

      StringBuffer fun = new StringBuffer("function _fromctor (");
      for (int j = 1; j < callStmt.getNumberOfUses() - 1; j++) {
        if (j != 1) fun.append(",");
        fun.append(ST.getStringValue(callStmt.getUse(j)));
      }

      fun.append(") {");
      fun.append(ST.getStringValue(callStmt.getUse(callStmt.getNumberOfUses() - 1)));
      fun.append("}");

      try {
        String fileName = "ctor$" + ++ctorCount;
        File f = new File(System.getProperty("java.io.tmpdir") + File.separator + fileName);
        FileWriter FO = new FileWriter(f);
        FO.write(fun.toString());
        FO.close();

        Set<String> fnNames =
            JSCallGraphUtil.loadAdditionalFile(cha, cl, fileName, f.toURI().toURL());
        IClass fcls = null;
        for (String nm : fnNames) {
          if (nm.endsWith("_fromctor")) {
            fcls = cl.lookupClass(nm, cha);
          }
        }

        assert fcls != null : "cannot find class for " + fileName + " in " + f;

        f.delete();

        if (DEBUG) System.err.println(("looking for ctor " + ctorCount + " and got " + fcls));

        if (fcls != null) return makeFunctionConstructor(cls, fcls);

      } catch (IOException e) {

      }

      return makeFunctionConstructor(cls, cls);
    }
  }
Beispiel #14
0
 public static boolean isRemoteProcedure(MethodReference method, IClassHierarchy cha) {
   return isCapsuleInterface(cha.lookupClass(method.getDeclaringClass()));
 }