use of org.objectweb.asm.Opcodes.POP in project groovy by apache.
the class StaticTypesCallSiteWriter method writeListDotProperty.
private void writeListDotProperty(final Expression receiver, final String propertyName, final boolean safe) {
// for lists, replace list.foo with:
// def result = new ArrayList(list.size())
// for (item in list) result.add(item.foo)
// result
ClassNode componentType = receiver.getNodeMetaData(StaticCompilationMetadataKeys.COMPONENT_TYPE);
if (componentType == null) {
componentType = OBJECT_TYPE;
}
CompileStack compileStack = controller.getCompileStack();
MethodVisitor mv = controller.getMethodVisitor();
Label exit = new Label();
if (safe) {
receiver.visit(controller.getAcg());
Label doGet = new Label();
mv.visitJumpInsn(IFNONNULL, doGet);
controller.getOperandStack().remove(1);
mv.visitInsn(ACONST_NULL);
mv.visitJumpInsn(GOTO, exit);
mv.visitLabel(doGet);
}
Variable tmpList = varX("tmpList", ClassHelper.make(ArrayList.class));
int var = compileStack.defineTemporaryVariable(tmpList, false);
Variable iterator = varX("iterator", Iterator_TYPE);
int it = compileStack.defineTemporaryVariable(iterator, false);
Variable nextVar = varX("next", componentType);
final int next = compileStack.defineTemporaryVariable(nextVar, false);
mv.visitTypeInsn(NEW, "java/util/ArrayList");
mv.visitInsn(DUP);
receiver.visit(controller.getAcg());
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "size", "()I", true);
controller.getOperandStack().remove(1);
mv.visitMethodInsn(INVOKESPECIAL, "java/util/ArrayList", "<init>", "(I)V", false);
mv.visitVarInsn(ASTORE, var);
Label l1 = new Label();
mv.visitLabel(l1);
receiver.visit(controller.getAcg());
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "iterator", "()Ljava/util/Iterator;", true);
controller.getOperandStack().remove(1);
mv.visitVarInsn(ASTORE, it);
Label l2 = new Label();
mv.visitLabel(l2);
mv.visitVarInsn(ALOAD, it);
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "hasNext", "()Z", true);
Label l3 = new Label();
mv.visitJumpInsn(IFEQ, l3);
mv.visitVarInsn(ALOAD, it);
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "next", "()Ljava/lang/Object;", true);
mv.visitTypeInsn(CHECKCAST, BytecodeHelper.getClassInternalName(componentType));
mv.visitVarInsn(ASTORE, next);
Label l4 = new Label();
mv.visitLabel(l4);
mv.visitVarInsn(ALOAD, var);
PropertyExpression pexp = propX(bytecodeX(componentType, v -> v.visitVarInsn(ALOAD, next)), propertyName);
pexp.visit(controller.getAcg());
controller.getOperandStack().box();
controller.getOperandStack().remove(1);
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "add", "(Ljava/lang/Object;)Z", true);
mv.visitInsn(POP);
Label l5 = new Label();
mv.visitLabel(l5);
mv.visitJumpInsn(GOTO, l2);
mv.visitLabel(l3);
mv.visitVarInsn(ALOAD, var);
if (safe) {
mv.visitLabel(exit);
}
controller.getOperandStack().push(ClassHelper.make(ArrayList.class));
controller.getCompileStack().removeVar(next);
controller.getCompileStack().removeVar(it);
controller.getCompileStack().removeVar(var);
}
use of org.objectweb.asm.Opcodes.POP in project sonar-java by SonarSource.
the class BytecodeEGWalker method branchingState.
@VisibleForTesting
ProgramState branchingState(Instruction terminator, ProgramState programState) {
ProgramState.Pop pop;
ProgramState ps;
List<ProgramState.SymbolicValueSymbol> symbolicValueSymbols;
switch(terminator.opcode) {
case IFEQ:
case IFNE:
case IFLT:
case IFGE:
case IFGT:
case IFLE:
pop = programState.unstackValue(1);
SymbolicValue svZero = new SymbolicValue();
symbolicValueSymbols = ImmutableList.of(new ProgramState.SymbolicValueSymbol(svZero, null), pop.valuesAndSymbols.get(0));
List<ProgramState> programStates = svZero.setConstraint(pop.state, DivisionByZeroCheck.ZeroConstraint.ZERO).stream().flatMap(s -> svZero.setConstraint(s, BooleanConstraint.FALSE).stream()).collect(Collectors.toList());
Preconditions.checkState(programStates.size() == 1);
ps = programStates.get(0);
break;
case IF_ICMPEQ:
case IF_ICMPNE:
case IF_ICMPLT:
case IF_ICMPGE:
case IF_ICMPGT:
case IF_ICMPLE:
case IF_ACMPEQ:
case IF_ACMPNE:
pop = programState.unstackValue(2);
symbolicValueSymbols = pop.valuesAndSymbols;
ps = pop.state;
break;
case IFNULL:
case IFNONNULL:
pop = programState.unstackValue(1);
symbolicValueSymbols = ImmutableList.of(new ProgramState.SymbolicValueSymbol(SymbolicValue.NULL_LITERAL, null), pop.valuesAndSymbols.get(0));
ps = pop.state;
break;
default:
throw new IllegalStateException("Unexpected terminator " + terminator);
}
return ps.stackValue(constraintManager.createBinarySymbolicValue(terminator, symbolicValueSymbols));
}
use of org.objectweb.asm.Opcodes.POP in project sonar-java by SonarSource.
the class BytecodeEGWalker method handleMethodInvocation.
private boolean handleMethodInvocation(Instruction instruction) {
boolean isStatic = instruction.opcode == Opcodes.INVOKESTATIC;
int arity = isStatic ? instruction.arity() : (instruction.arity() + 1);
ProgramState.Pop pop = programState.unstackValue(arity);
Preconditions.checkState(pop.values.size() == arity, "Arguments mismatch for INVOKE");
// TODO use constraintManager.createMethodSymbolicValue to create relational SV for equals
programState = pop.state;
SymbolicValue returnSV = instruction.hasReturnValue() ? constraintManager.createSymbolicValue(instruction) : null;
String signature = instruction.fieldOrMethod.completeSignature();
MethodBehavior methodInvokedBehavior = behaviorCache.get(signature);
enqueueUncheckedExceptions();
// FIXME : empty yields here should not happen, for now act as if behavior was not resolved.
if (methodInvokedBehavior != null && methodInvokedBehavior.isComplete() && !methodInvokedBehavior.yields().isEmpty()) {
List<SymbolicValue> stack = Lists.reverse(pop.values);
if (!isStatic) {
// remove "thisSV" from stack before trying to apply any yield, as it should not match with arguments
stack = stack.subList(1, stack.size());
}
List<SymbolicValue> arguments = stack;
methodInvokedBehavior.happyPathYields().forEach(yield -> yield.statesAfterInvocation(arguments, Collections.emptyList(), programState, () -> returnSV).forEach(ps -> {
checkerDispatcher.methodYield = yield;
if (ps.peekValue() != null) {
ps = setDoubleOrLong(ps, ps.peekValue(), instruction.isLongOrDoubleValue());
}
checkerDispatcher.addTransition(ps);
checkerDispatcher.methodYield = null;
}));
methodInvokedBehavior.exceptionalPathYields().forEach(yield -> {
Type exceptionType = yield.exceptionType(semanticModel);
yield.statesAfterInvocation(arguments, Collections.emptyList(), programState, () -> constraintManager.createExceptionalSymbolicValue(exceptionType)).forEach(ps -> {
ps.storeExitValue();
enqueueExceptionHandlers(exceptionType, ps);
});
});
return true;
}
if (methodInvokedBehavior != null) {
methodInvokedBehavior.getDeclaredExceptions().forEach(exception -> {
Type exceptionType = semanticModel.getClassType(exception);
ProgramState ps = programState.stackValue(constraintManager.createExceptionalSymbolicValue(exceptionType));
enqueueExceptionHandlers(exceptionType, ps);
});
}
if (instruction.hasReturnValue()) {
programState = programState.stackValue(returnSV);
programState = setDoubleOrLong(returnSV, instruction.isLongOrDoubleValue());
}
return false;
}
Aggregations