/** * Get simple unqualified type name. * * @param typ Type Reference. * @return String Unqualified type name. */ private static String getSimpleTypeName(TypeReference typ) { final Map<String, String> mapFullTypeName = ImmutableMap.<String, String>builder() .put("B", "byte") .put("C", "char") .put("D", "double") .put("F", "float") .put("I", "int") .put("J", "long") .put("S", "short") .put("Z", "boolean") .build(); if (typ.isArrayType()) return "Array"; String typName = typ.getName().toString(); if (typName.startsWith("L")) { typName = typName.split("<")[0].substring(1); // handle generics typName = typName.substring(typName.lastIndexOf('/') + 1); // get unqualified name typName = typName.substring(typName.lastIndexOf('$') + 1); // handle inner classes } else { typName = mapFullTypeName.get(typName); } return typName; } }
/** * Does 'this' refer to a class? */ public final boolean isClassType() { return !isArrayType() && !isPrimitiveType(); }
/** * Does 'this' refer to a class? */ public final boolean isClassType() { return !isArrayType() && !isPrimitiveType(); }
public int getDimensionality() { assert isArrayType(); int mask = getDerivedMask(); if ((mask&PrimitiveMask) == PrimitiveMask) { mask >>= ElementBits; } int dims = 0; while ((mask&ArrayMask) == ArrayMask) { mask >>= ElementBits; dims++; } assert dims>0; return dims; }
public int getDimensionality() { assert isArrayType(); int mask = getDerivedMask(); if ((mask&PrimitiveMask) == PrimitiveMask) { mask >>= ElementBits; } int dims = 0; while ((mask&ArrayMask) == ArrayMask) { mask >>= ElementBits; dims++; } assert dims>0; return dims; }
@Override public void visitNew(SSANewInstruction instruction) { TypeReference declaredType = instruction.getNewSite().getDeclaredType(); // check for multidimensional array if (declaredType.isArrayType() && declaredType.getArrayElementType().isArrayType()) { arrayWrites.add(new MemoryAccess(instructionIndex, node)); } }
@Override public void visitNew(NewInstruction instruction) { TypeReference tr = ShrikeUtil.makeTypeReference(loader, instruction.getType()); // chekc for multi-dimensional array allocation if (tr.isArrayType() && tr.getArrayElementType().isArrayType()) { if (DEBUG) { System.err.println("found multi-dim array write at " + instructionIndex); } arrayWrites.add(new MemoryAccess(instructionIndex, node)); } }
@Override public void visitNew(NewInstruction instruction) { TypeReference tr = ShrikeUtil.makeTypeReference(loader, instruction.getType()); // chekc for multi-dimensional array allocation if (tr.isArrayType() && tr.getArrayElementType().isArrayType()) { if (DEBUG) { System.err.println("found multi-dim array write at " + instructionIndex); } arrayWrites.add(new MemoryAccess(instructionIndex, node)); } }
@Override public void visitNew(SSANewInstruction instruction) { TypeReference declaredType = instruction.getNewSite().getDeclaredType(); // check for multidimensional array if (declaredType.isArrayType() && declaredType.getArrayElementType().isArrayType()) { arrayWrites.add(new MemoryAccess(instructionIndex, node)); } }
/** * Add a New statement of the given array type and length */ public SSANewInstruction add1DArrayAllocation(TypeReference T, int length) { int instance = nextLocal++; NewSiteReference ref = NewSiteReference.make(statements.size(), T); assert T.isArrayType(); assert ((ArrayClass)cha.lookupClass(T)).getDimensionality() == 1; int[] sizes = new int[1]; Arrays.fill(sizes, getValueNumberForIntConstant(length)); SSANewInstruction result = insts.NewInstruction(statements.size(), instance, ref, sizes); statements.add(result); cache.invalidate(this, Everywhere.EVERYWHERE); return result; }
/** * Add a New statement of the given array type and length */ public SSANewInstruction add1DArrayAllocation(TypeReference T, int length) { int instance = nextLocal++; NewSiteReference ref = NewSiteReference.make(statements.size(), T); assert T.isArrayType(); assert ((ArrayClass)cha.lookupClass(T)).getDimensionality() == 1; int[] sizes = new int[1]; Arrays.fill(sizes, getValueNumberForIntConstant(length)); SSANewInstruction result = insts.NewInstruction(statements.size(), instance, ref, sizes); statements.add(result); cache.invalidate(this, Everywhere.EVERYWHERE); return result; }
/** * Set up a method summary which allocates and returns an instance of concrete type T. */ private void addStatementsForConcreteType(final TypeReference T) { int alloc = addStatementsForConcreteSimpleType(T); if (alloc == -1) { return; } if (T.isArrayType()) { MethodReference init = MethodReference.findOrCreate(T, MethodReference.initAtom, MethodReference.defaultInitDesc); CallSiteReference site = CallSiteReference.make(getCallSiteForType(T), init, IInvokeInstruction.Dispatch.SPECIAL); int[] params = new int[1]; params[0] = alloc; int exc = getExceptionsForType(T); SSAInvokeInstruction s = insts.InvokeInstruction(allInstructions.size(), params, exc, site, null); calls.add(s); allInstructions.add(s); } }
/** * Set up a method summary which allocates and returns an instance of concrete type T. */ private void addStatementsForConcreteType(final TypeReference T) { int alloc = addStatementsForConcreteSimpleType(T); if (alloc == -1) { return; } if (T.isArrayType()) { MethodReference init = MethodReference.findOrCreate(T, MethodReference.initAtom, MethodReference.defaultInitDesc); CallSiteReference site = CallSiteReference.make(getCallSiteForType(T), init, IInvokeInstruction.Dispatch.SPECIAL); int[] params = new int[1]; params[0] = alloc; int exc = getExceptionsForType(T); SSAInvokeInstruction s = insts.InvokeInstruction(allInstructions.size(), params, exc, site, null); calls.add(s); allInstructions.add(s); } }
/** * for an array class, get the innermost type, or null if it's primitive */ private IClass getInnermostTypeOfArrayClass(IClass klass) { TypeReference result = klass.getReference(); while (result.isArrayType()) { result = result.getArrayElementType(); } return result.isPrimitiveType() ? null : lookupClass(result); }
/** * Create a new instruction to allocate an array. * * @throws IllegalArgumentException if site is null * @throws IllegalArgumentException if params is null */ protected SSANewInstruction(int iindex, int result, NewSiteReference site, int[] params) { super(iindex); if (params == null) { throw new IllegalArgumentException("params is null"); } if (site == null) { throw new IllegalArgumentException("site is null"); } assert site.getDeclaredType().isArrayType() || site.getDeclaredType().getClassLoader().getLanguage() != ClassLoaderReference.Java; this.result = result; this.site = site; this.params = params.clone(); }
@Override public Collection<TypeReference> getExceptionTypes() { if (getNewSite().getDeclaredType().isArrayType()) { return getNewArrayExceptions(); } else { return getNewScalarExceptions(); } } };
@Override public Collection<TypeReference> getExceptionTypes() { if (getNewSite().getDeclaredType().isArrayType()) { return getNewArrayExceptions(); } else { return getNewScalarExceptions(); } } };
/** * for an array class, get the innermost type, or null if it's primitive */ private IClass getInnermostTypeOfArrayClass(IClass klass) { TypeReference result = klass.getReference(); while (result.isArrayType()) { result = result.getArrayElementType(); } return result.isPrimitiveType() ? null : lookupClass(result); }
@Test public void testArrayLiteral1() throws IllegalArgumentException, CancelException, IOException { runTest(singleTestSrc(), rtJar, simpleTestEntryPoint(), Collections.singletonList( cg -> { MethodReference mref = descriptorToMethodRef("Source#ArrayLiteral1#main#([Ljava/lang/String;)V", cg.getClassHierarchy()); CGNode node = cg.getNodes(mref).iterator().next(); SSAInstruction s = node.getIR().getInstructions()[2]; Assert.assertTrue("Did not find new array instruction.", s instanceof SSANewInstruction); Assert.assertTrue("", ((SSANewInstruction) s).getNewSite().getDeclaredType().isArrayType()); }), true, null); }
/** * @see com.ibm.wala.shrikeBT.IInstruction.Visitor#visitNew(NewInstruction) */ @Override public void visitNew(com.ibm.wala.shrikeBT.NewInstruction instruction) { int result = reuseOrCreateDef(); TypeReference t = ShrikeUtil.makeTypeReference(loader, instruction.getType()); NewSiteReference ref = NewSiteReference.make(getCurrentProgramCounter(), t); if (t.isArrayType()) { int[] sizes = new int[instruction.getArrayBoundsCount()]; for (int i = 0; i < instruction.getArrayBoundsCount(); i++) { sizes[instruction.getArrayBoundsCount() - 1 - i] = workingState.pop(); } emitInstruction(insts.NewInstruction(getCurrentInstructionIndex(), result, ref, sizes)); } else { emitInstruction(insts.NewInstruction(getCurrentInstructionIndex(), result, ref)); popN(instruction); } workingState.push(result); }