private static boolean isNull(BasicValue value) { if (null == value) return true; if (!value.isReference()) return false; Type type = value.getType(); return "Lnull;".equals(type.getDescriptor()); }
static boolean isNull(BasicValue value) { if (null == value) return true; if (!value.isReference()) return false; Type type = value.getType(); return "Lnull;".equals(type.getDescriptor()); }
static boolean isNull(BasicValue value) { if (null == value) return true; if (!value.isReference()) return false; Type type = value.getType(); return "Lnull;".equals(type.getDescriptor()); }
static boolean isNull(BasicValue value) { if (null == value) return true; if (!value.isReference()) return false; Type type = value.getType(); return "Lnull;".equals(type.getDescriptor()); }
@Override protected boolean isArrayValue(final BasicValue value) { Type t = value.getType(); return t != null && ("Lnull;".equals(t.getDescriptor()) || t.getSort() == Type.ARRAY); }
static boolean isNull(BasicValue value) { if (null == value) { return true; } if (!value.isReference()) { return false; } final Type type= value.getType(); return "Lnull;".equals(type.getDescriptor()); }
static boolean isNull(BasicValue value) { if (null == value) return true; if (!value.isReference()) return false; Type type = value.getType(); return "Lnull;".equals(type.getDescriptor()); }
static boolean isNullType(BasicValue v) { return (v == BasicValue.UNINITIALIZED_VALUE) || (v.isReference() && v.getType().getInternalName().equals("null")); }
@Override protected BasicValue getElementValue(final BasicValue objectArrayValue) throws AnalyzerException { Type arrayType = objectArrayValue.getType(); if (arrayType != null) { if (arrayType.getSort() == Type.ARRAY) { return newValue(Type.getType(arrayType.getDescriptor() .substring(1))); } else if ("Lnull;".equals(arrayType.getDescriptor())) { return objectArrayValue; } } throw new Error("Internal error"); }
private void emitStoreValue(MethodVisitor mv, BasicValue v, int lvarStack, int idx) throws InternalError, IndexOutOfBoundsException { String desc; switch (v.getType().getSort()) { case Type.OBJECT: case Type.ARRAY: desc = "(Ljava/lang/Object;L" + STACK_NAME + ";I)V"; break; case Type.BOOLEAN: case Type.BYTE: case Type.SHORT: case Type.CHAR: case Type.INT: desc = "(IL" + STACK_NAME + ";I)V"; break; case Type.FLOAT: desc = "(FL" + STACK_NAME + ";I)V"; break; case Type.LONG: desc = "(JL" + STACK_NAME + ";I)V"; break; case Type.DOUBLE: desc = "(DL" + STACK_NAME + ";I)V"; break; default: throw new InternalError("Unexpected type: " + v.getType()); } mv.visitVarInsn(Opcodes.ALOAD, lvarStack); emitConst(mv, idx); mv.visitMethodInsn(Opcodes.INVOKESTATIC, STACK_NAME, "push", desc); }
@Override public void returnOperation(final AbstractInsnNode insn, final BasicValue value, final BasicValue expected) throws AnalyzerException { Preconditions.checkState(insn.getOpcode() == ARETURN); Preconditions.checkState(unwrap(value).getType().equals( Type.getType(Rule.class))); Preconditions.checkState(unwrap(expected).getType().equals( Type.getType(Rule.class))); Preconditions.checkState(method.getReturnInstructionNode() == null); method.setReturnInstructionNode(createNode(insn, null, value)); }
@Override public BasicValue binaryOperation(AbstractInsnNode insn, BasicValue value1, BasicValue value2) throws AnalyzerException { if(insn.getOpcode() == Opcodes.AALOAD) { Type t1 = value1.getType(); if(t1 == null || t1.getSort() != Type.ARRAY) { throw new AnalyzerException(insn, "AALOAD needs an array as first parameter"); } Type resultType = Type.getType(t1.getDescriptor().substring(1)); return new BasicValue(resultType); } return super.binaryOperation(insn, value1, value2); }
@Override protected boolean isSubTypeOf(final BasicValue value, final BasicValue expected) { Type expectedType = expected.getType(); Type type = value.getType(); switch (expectedType.getSort()) { case Type.INT: case Type.FLOAT: case Type.LONG: case Type.DOUBLE: return type.equals(expectedType); case Type.ARRAY: case Type.OBJECT: if ("Lnull;".equals(type.getDescriptor())) { return true; } else if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) { return isAssignableFrom(expectedType, type); } else { return false; } default: throw new Error("Internal error"); } }
private void extractFields(InstructionGroup group) { List<FieldNode> fields = group.getFields(); for (InstructionGraphNode node : group.getNodes()) { if (node.isXLoad()) { VarInsnNode insn = (VarInsnNode) node.getInstruction(); // check whether we already have a field for the var with this index int index; for (index = 0; index < fields.size(); index++) { if (fields.get(index).access == insn.var) break; } // if we don't, create a new field for the var if (index == fields.size()) { // CAUTION, HACK!: for brevity we reuse the access field and the value field of the FieldNode // for keeping track of the original var index as well as the FieldNodes Type (respectively) // so we need to make sure that we correct for this when the field is actually written Type type = node.getResultValue().getType(); fields.add(new FieldNode(insn.var, "field$" + index, type.getDescriptor(), null, type)); } // normalize the instruction so instruction groups that are identical except for the variable // indexes are still mapped to the same group class (name) insn.var = index; } } }
@Override public BasicValue merge(BasicValue v, BasicValue w) { if (!v.equals(w)) { Type t = v.getType(); Type u = w.getType(); if (t != null && (t.getSort() == Type.OBJECT || t.getSort() == Type.ARRAY)) { if (u != null && (u.getSort() == Type.OBJECT || u.getSort() == Type.ARRAY)) { if ("Lnull;".equals(t.getDescriptor())) { return w; } if ("Lnull;".equals(u.getDescriptor())) { return v; } if (isAssignableFrom(t, u)) { return v; } if (isAssignableFrom(u, t)) { return w; } return new BasicValue(inheritanceLookup.getCommonSuperType(t, u)); } } return BasicValue.UNINITIALIZED_VALUE; } return v; }
@Override public BasicValue merge(BasicValue v, BasicValue w) { if (!v.equals(w)) { Type t = v.getType(); Type u = w.getType(); if (t != null && (t.getSort() == Type.OBJECT || t.getSort() == Type.ARRAY)) { if (u != null && (u.getSort() == Type.OBJECT || u.getSort() == Type.ARRAY)) { if ("Lnull;".equals(t.getDescriptor())) { return w; } if ("Lnull;".equals(u.getDescriptor())) { return v; } if (isAssignableFrom(t, u)) { return v; } if (isAssignableFrom(u, t)) { return w; } return new BasicValue(inheritanceLookup.getCommonSuperType(t, u)); } } return BasicValue.UNINITIALIZED_VALUE; } return v; }
private void emitNewAndDup(MethodVisitor mv, Frame frame, int stackIndex, MethodInsnNode min) { int arguments = frame.getStackSize() - stackIndex - 1; int neededLocals = 0; for (int i = arguments; i >= 1; i--) { BasicValue v = (BasicValue) frame.getStack(stackIndex + i); mv.visitVarInsn(v.getType().getOpcode(Opcodes.ISTORE), lvarStack + 1 + neededLocals); neededLocals += v.getSize(); } db.log(LogLevel.DEBUG, "Inserting NEW & DUP for constructor call %s%s with %d arguments (%d locals)", min.owner, min.desc, arguments, neededLocals); if (additionalLocals < neededLocals) { additionalLocals = neededLocals; } ((NewValue) frame.getStack(stackIndex - 1)).insn.accept(mv); ((NewValue) frame.getStack(stackIndex)).insn.accept(mv); for (int i = 1; i <= arguments; i++) { BasicValue v = (BasicValue) frame.getStack(stackIndex + i); neededLocals -= v.getSize(); mv.visitVarInsn(v.getType().getOpcode(Opcodes.ILOAD), lvarStack + 1 + neededLocals); } }
@Override public BasicValue binaryOperation(final AbstractInsnNode insn, final BasicValue value1, final BasicValue value2) throws AnalyzerException { /* * We're looking for the assignment of a local holder objectref to a member variable. * If we spot that, then the local holder can't be replaced, since we don't (yet) * have the mechanics to replace the member variable with the holder's members or * to assign all of them when this happens. */ if (insn.getOpcode() == Opcodes.PUTFIELD) { if (value2.isReference() && (value1 instanceof ReplacingBasicValue)) { final ReplacingBasicValue possibleThis = (ReplacingBasicValue) value1; if (possibleThis.isThis() && (value2 instanceof ReplacingBasicValue)) { // if this is a reference for a holder class, we can't replace it if (HOLDERS.get(value2.getType().getDescriptor()) != null) { final ReplacingBasicValue localRef = (ReplacingBasicValue) value2; localRef.setAssignedToMember(); } } } } return super.binaryOperation(insn, value1, value2); }
@Override public void returnOperation(AbstractInsnNode insn, BasicValue value, BasicValue expected) throws AnalyzerException { checkState(insn.getOpcode() == ARETURN); checkState(unwrap(value).getType().equals(Types.RULE)); checkState(unwrap(expected).getType().equals(Types.RULE)); checkState(method.getReturnInstructionNode() == null); method.setReturnInstructionNode(createNode(insn, null, value)); }
@Override public BasicValue newValue(final Type type) { if (type == null) { return BasicValue.UNINITIALIZED_VALUE; } boolean isArray = type.getSort() == Type.ARRAY; if (isArray) { switch (type.getElementType().getSort()) { case Type.BOOLEAN: case Type.CHAR: case Type.BYTE: case Type.SHORT: return new BasicValue(type); } } BasicValue v = super.newValue(type); if (BasicValue.REFERENCE_VALUE.equals(v)) { if (isArray) { v = newValue(type.getElementType()); String desc = v.getType().getDescriptor(); for (int i = 0; i < type.getDimensions(); ++i) { desc = '[' + desc; } v = new BasicValue(Type.getType(desc)); } else { v = new BasicValue(type); } } return v; }