private static Type getBoxedType(final Type type) { switch (type.getSort()) { case Type.BYTE: return BYTE_TYPE; case Type.BOOLEAN: return BOOLEAN_TYPE; case Type.SHORT: return SHORT_TYPE; case Type.CHAR: return CHARACTER_TYPE; case Type.INT: return INTEGER_TYPE; case Type.FLOAT: return FLOAT_TYPE; case Type.LONG: return LONG_TYPE; case Type.DOUBLE: return DOUBLE_TYPE; } return type; }
@Override public BasicValue newValue(final Type type) { if (type == null) { return BasicValue.UNINITIALIZED_VALUE; } switch (type.getSort()) { case Type.VOID: return null; case Type.BOOLEAN: case Type.CHAR: case Type.BYTE: case Type.SHORT: case Type.INT: return BasicValue.INT_VALUE; case Type.FLOAT: return BasicValue.FLOAT_VALUE; case Type.LONG: return BasicValue.LONG_VALUE; case Type.DOUBLE: return BasicValue.DOUBLE_VALUE; case Type.ARRAY: case Type.OBJECT: return BasicValue.REFERENCE_VALUE; default: throw new Error("Internal error"); } }
protected Class<?> getClass(final Type t) { try { if (t.getSort() == Type.ARRAY) { return Class.forName(t.getDescriptor().replace('/', '.'), false, loader); } return Class.forName(t.getClassName(), false, loader); } catch (ClassNotFoundException e) { throw new RuntimeException(e.toString()); } } }
@Override protected boolean isArrayValue(final BasicValue value) { Type t = value.getType(); return t != null && ("Lnull;".equals(t.getDescriptor()) || t.getSort() == Type.ARRAY); }
void checkLDCConstant(final Object cst) { if (cst instanceof Type) { int s = ((Type) cst).getSort(); if (s != Type.OBJECT && s != Type.ARRAY && s != Type.METHOD) { throw new IllegalArgumentException("Illegal LDC constant value"); } if (s != Type.METHOD && (version & 0xFFFF) < Opcodes.V1_5) { throw new IllegalArgumentException( "ldc of a constant class requires at least version 1.5"); } if (s == Type.METHOD && (version & 0xFFFF) < Opcodes.V1_7) { throw new IllegalArgumentException( "ldc of a method type requires at least version 1.7"); } } else if (cst instanceof Handle) { if ((version & 0xFFFF) < Opcodes.V1_7) { throw new IllegalArgumentException( "ldc of a handle requires at least version 1.7"); } int tag = ((Handle) cst).getTag(); if (tag < Opcodes.H_GETFIELD || tag > Opcodes.H_INVOKEINTERFACE) { throw new IllegalArgumentException("invalid handle tag " + tag); } } else { checkConstant(cst); } }
@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"); } }
/** * Generates the instructions to box the top stack value using Java 5's * valueOf() method. This value is replaced by its boxed equivalent on top * of the stack. * * @param type * the type of the top stack value. */ public void valueOf(final Type type) { if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) { return; } if (type == Type.VOID_TYPE) { push((String) null); } else { Type boxed = getBoxedType(type); invokeStatic(boxed, new Method("valueOf", boxed, new Type[] { type })); } }
@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"); }
@Override public void visit(final String name, final Object value) { checkEnd(); checkName(name); if (!(value instanceof Byte || value instanceof Boolean || value instanceof Character || value instanceof Short || value instanceof Integer || value instanceof Long || value instanceof Float || value instanceof Double || value instanceof String || value instanceof Type || value instanceof byte[] || value instanceof boolean[] || value instanceof char[] || value instanceof short[] || value instanceof int[] || value instanceof long[] || value instanceof float[] || value instanceof double[])) { throw new IllegalArgumentException("Invalid annotation value"); } if (value instanceof Type) { int sort = ((Type) value).getSort(); if (sort == Type.METHOD) { throw new IllegalArgumentException("Invalid annotation value"); } } if (av != null) { av.visit(name, value); } }
switch (type.getSort()) { case Type.BOOLEAN: typ = Opcodes.T_BOOLEAN;
public void newarray(final Type type) { int typ; switch (type.getSort()) { case Type.BOOLEAN: typ = Opcodes.T_BOOLEAN;
/** * Generates an invoke method instruction. * * @param opcode * the instruction's opcode. * @param type * the class in which the method is defined. * @param method * the method to be invoked. */ private void invokeInsn(final int opcode, final Type type, final Method method, final boolean itf) { String owner = type.getSort() == Type.ARRAY ? type.getDescriptor() : type.getInternalName(); mv.visitMethodInsn(opcode, owner, method.getName(), method.getDescriptor(), itf); }
/** * Generates the instructions to box the top stack value. This value is * replaced by its boxed equivalent on top of the stack. * * @param type * the type of the top stack value. */ public void box(final Type type) { if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) { return; } if (type == Type.VOID_TYPE) { push((String) null); } else { Type boxed = getBoxedType(type); newInstance(boxed); if (type.getSize() == 2) { // Pp -> Ppo -> oPpo -> ooPpo -> ooPp -> o dupX2(); dupX2(); pop(); } else { // p -> po -> opo -> oop -> o dupX1(); swap(); } invokeConstructor(boxed, new Method("<init>", Type.VOID_TYPE, new Type[] { type })); } }
public String mapDesc(String desc) { Type t = Type.getType(desc); switch (t.getSort()) { case Type.ARRAY: String s = mapDesc(t.getElementType().getDescriptor()); for (int i = 0; i < t.getDimensions(); ++i) { s = '[' + s; } return s; case Type.OBJECT: String newType = map(t.getInternalName()); if (newType != null) { return 'L' + newType + ';'; } } return desc; }
@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; }
push("java/lang/String"); } else if (cst instanceof Type) { int sort = ((Type) cst).getSort(); if (sort == Type.OBJECT || sort == Type.ARRAY) { push("java/lang/Class");
private Type mapType(Type t) { switch (t.getSort()) { case Type.ARRAY: String s = mapDesc(t.getElementType().getDescriptor()); for (int i = 0; i < t.getDimensions(); ++i) { s = '[' + s; } return Type.getType(s); case Type.OBJECT: s = map(t.getInternalName()); return s != null ? Type.getObjectType(s) : t; case Type.METHOD: return Type.getMethodType(mapMethodDesc(t.getDescriptor())); } return t; }