use of org.apache.tapestry5.internal.plastic.asm.tree.analysis.BasicValue in project tapestry-5 by apache.
the class BasicVerifier method naryOperation.
@Override
public BasicValue naryOperation(final AbstractInsnNode insn, final List<? extends BasicValue> values) throws AnalyzerException {
int opcode = insn.getOpcode();
if (opcode == MULTIANEWARRAY) {
for (BasicValue value : values) {
if (!BasicValue.INT_VALUE.equals(value)) {
throw new AnalyzerException(insn, null, BasicValue.INT_VALUE, value);
}
}
} else {
int i = 0;
int j = 0;
if (opcode != INVOKESTATIC && opcode != INVOKEDYNAMIC) {
Type owner = Type.getObjectType(((MethodInsnNode) insn).owner);
if (!isSubTypeOf(values.get(i++), newValue(owner))) {
throw new AnalyzerException(insn, "Method owner", newValue(owner), values.get(0));
}
}
String methodDescriptor = (opcode == INVOKEDYNAMIC) ? ((InvokeDynamicInsnNode) insn).desc : ((MethodInsnNode) insn).desc;
Type[] args = Type.getArgumentTypes(methodDescriptor);
while (i < values.size()) {
BasicValue expected = newValue(args[j++]);
BasicValue actual = values.get(i++);
if (!isSubTypeOf(actual, expected)) {
throw new AnalyzerException(insn, "Argument " + j, expected, actual);
}
}
}
return super.naryOperation(insn, values);
}
use of org.apache.tapestry5.internal.plastic.asm.tree.analysis.BasicValue in project tapestry-5 by apache.
the class BasicVerifier method binaryOperation.
@Override
public BasicValue binaryOperation(final AbstractInsnNode insn, final BasicValue value1, final BasicValue value2) throws AnalyzerException {
BasicValue expected1;
BasicValue expected2;
switch(insn.getOpcode()) {
case IALOAD:
expected1 = newValue(Type.getType("[I"));
expected2 = BasicValue.INT_VALUE;
break;
case BALOAD:
if (isSubTypeOf(value1, newValue(Type.getType("[Z")))) {
expected1 = newValue(Type.getType("[Z"));
} else {
expected1 = newValue(Type.getType("[B"));
}
expected2 = BasicValue.INT_VALUE;
break;
case CALOAD:
expected1 = newValue(Type.getType("[C"));
expected2 = BasicValue.INT_VALUE;
break;
case SALOAD:
expected1 = newValue(Type.getType("[S"));
expected2 = BasicValue.INT_VALUE;
break;
case LALOAD:
expected1 = newValue(Type.getType("[J"));
expected2 = BasicValue.INT_VALUE;
break;
case FALOAD:
expected1 = newValue(Type.getType("[F"));
expected2 = BasicValue.INT_VALUE;
break;
case DALOAD:
expected1 = newValue(Type.getType("[D"));
expected2 = BasicValue.INT_VALUE;
break;
case AALOAD:
expected1 = newValue(Type.getType("[Ljava/lang/Object;"));
expected2 = BasicValue.INT_VALUE;
break;
case IADD:
case ISUB:
case IMUL:
case IDIV:
case IREM:
case ISHL:
case ISHR:
case IUSHR:
case IAND:
case IOR:
case IXOR:
case IF_ICMPEQ:
case IF_ICMPNE:
case IF_ICMPLT:
case IF_ICMPGE:
case IF_ICMPGT:
case IF_ICMPLE:
expected1 = BasicValue.INT_VALUE;
expected2 = BasicValue.INT_VALUE;
break;
case FADD:
case FSUB:
case FMUL:
case FDIV:
case FREM:
case FCMPL:
case FCMPG:
expected1 = BasicValue.FLOAT_VALUE;
expected2 = BasicValue.FLOAT_VALUE;
break;
case LADD:
case LSUB:
case LMUL:
case LDIV:
case LREM:
case LAND:
case LOR:
case LXOR:
case LCMP:
expected1 = BasicValue.LONG_VALUE;
expected2 = BasicValue.LONG_VALUE;
break;
case LSHL:
case LSHR:
case LUSHR:
expected1 = BasicValue.LONG_VALUE;
expected2 = BasicValue.INT_VALUE;
break;
case DADD:
case DSUB:
case DMUL:
case DDIV:
case DREM:
case DCMPL:
case DCMPG:
expected1 = BasicValue.DOUBLE_VALUE;
expected2 = BasicValue.DOUBLE_VALUE;
break;
case IF_ACMPEQ:
case IF_ACMPNE:
expected1 = BasicValue.REFERENCE_VALUE;
expected2 = BasicValue.REFERENCE_VALUE;
break;
case PUTFIELD:
FieldInsnNode fieldInsn = (FieldInsnNode) insn;
expected1 = newValue(Type.getObjectType(fieldInsn.owner));
expected2 = newValue(Type.getType(fieldInsn.desc));
break;
default:
throw new AssertionError();
}
if (!isSubTypeOf(value1, expected1)) {
throw new AnalyzerException(insn, "First argument", expected1, value1);
} else if (!isSubTypeOf(value2, expected2)) {
throw new AnalyzerException(insn, "Second argument", expected2, value2);
}
if (insn.getOpcode() == AALOAD) {
return getElementValue(value1);
} else {
return super.binaryOperation(insn, value1, value2);
}
}
use of org.apache.tapestry5.internal.plastic.asm.tree.analysis.BasicValue in project tapestry-5 by apache.
the class CheckClassAdapter method printAnalyzerResult.
static void printAnalyzerResult(final MethodNode method, final Analyzer<BasicValue> analyzer, final PrintWriter printWriter) {
Textifier textifier = new Textifier();
TraceMethodVisitor traceMethodVisitor = new TraceMethodVisitor(textifier);
printWriter.println(method.name + method.desc);
for (int i = 0; i < method.instructions.size(); ++i) {
method.instructions.get(i).accept(traceMethodVisitor);
StringBuilder stringBuilder = new StringBuilder();
Frame<BasicValue> frame = analyzer.getFrames()[i];
if (frame == null) {
stringBuilder.append('?');
} else {
for (int j = 0; j < frame.getLocals(); ++j) {
stringBuilder.append(getUnqualifiedName(frame.getLocal(j).toString())).append(' ');
}
stringBuilder.append(" : ");
for (int j = 0; j < frame.getStackSize(); ++j) {
stringBuilder.append(getUnqualifiedName(frame.getStack(j).toString())).append(' ');
}
}
while (stringBuilder.length() < method.maxStack + method.maxLocals + 1) {
stringBuilder.append(' ');
}
printWriter.print(Integer.toString(i + 100000).substring(1));
printWriter.print(" " + stringBuilder + " : " + textifier.text.get(textifier.text.size() - 1));
}
for (TryCatchBlockNode tryCatchBlock : method.tryCatchBlocks) {
tryCatchBlock.accept(traceMethodVisitor);
printWriter.print(" " + textifier.text.get(textifier.text.size() - 1));
}
printWriter.println();
}
use of org.apache.tapestry5.internal.plastic.asm.tree.analysis.BasicValue in project tapestry-5 by apache.
the class CheckClassAdapter method verify.
/**
* Checks the given class.
*
* @param classReader the class to be checked.
* @param loader a <code>ClassLoader</code> which will be used to load referenced classes. May be
* {@literal null}.
* @param printResults whether to print the results of the bytecode verification.
* @param printWriter where the results (or the stack trace in case of error) must be printed.
*/
public static void verify(final ClassReader classReader, final ClassLoader loader, final boolean printResults, final PrintWriter printWriter) {
ClassNode classNode = new ClassNode();
classReader.accept(new CheckClassAdapter(/*latest*/
Opcodes.ASM10_EXPERIMENTAL, classNode, false) {
}, ClassReader.SKIP_DEBUG);
Type syperType = classNode.superName == null ? null : Type.getObjectType(classNode.superName);
List<MethodNode> methods = classNode.methods;
List<Type> interfaces = new ArrayList<>();
for (String interfaceName : classNode.interfaces) {
interfaces.add(Type.getObjectType(interfaceName));
}
for (MethodNode method : methods) {
SimpleVerifier verifier = new SimpleVerifier(Type.getObjectType(classNode.name), syperType, interfaces, (classNode.access & Opcodes.ACC_INTERFACE) != 0);
Analyzer<BasicValue> analyzer = new Analyzer<>(verifier);
if (loader != null) {
verifier.setClassLoader(loader);
}
try {
analyzer.analyze(classNode.name, method);
} catch (AnalyzerException e) {
e.printStackTrace(printWriter);
}
if (printResults) {
printAnalyzerResult(method, analyzer, printWriter);
}
}
printWriter.flush();
}
use of org.apache.tapestry5.internal.plastic.asm.tree.analysis.BasicValue in project tapestry-5 by apache.
the class SimpleVerifier method merge.
@Override
public BasicValue merge(final BasicValue value1, final BasicValue value2) {
if (!value1.equals(value2)) {
Type type1 = value1.getType();
Type type2 = value2.getType();
if (type1 != null && (type1.getSort() == Type.OBJECT || type1.getSort() == Type.ARRAY) && type2 != null && (type2.getSort() == Type.OBJECT || type2.getSort() == Type.ARRAY)) {
if (type1.equals(NULL_TYPE)) {
return value2;
}
if (type2.equals(NULL_TYPE)) {
return value1;
}
if (isAssignableFrom(type1, type2)) {
return value1;
}
if (isAssignableFrom(type2, type1)) {
return value2;
}
int numDimensions = 0;
if (type1.getSort() == Type.ARRAY && type2.getSort() == Type.ARRAY && type1.getDimensions() == type2.getDimensions() && type1.getElementType().getSort() == Type.OBJECT && type2.getElementType().getSort() == Type.OBJECT) {
numDimensions = type1.getDimensions();
type1 = type1.getElementType();
type2 = type2.getElementType();
}
while (true) {
if (type1 == null || isInterface(type1)) {
return newArrayValue(Type.getObjectType("java/lang/Object"), numDimensions);
}
type1 = getSuperClass(type1);
if (isAssignableFrom(type1, type2)) {
return newArrayValue(type1, numDimensions);
}
}
}
return BasicValue.UNINITIALIZED_VALUE;
}
return value1;
}
Aggregations