public static ClassInfo getClassInfo(final Class clazz) { final Type type = Type.getType(clazz); final Type sc = (clazz.getSuperclass() == null) ? null : Type.getType(clazz.getSuperclass()); return new ClassInfo() { public Type getType() { return type; } public Type getSuperType() { return sc; } public Type[] getInterfaces() { return TypeUtils.getTypes(clazz.getInterfaces()); } public int getModifiers() { return clazz.getModifiers(); } }; }
public static void hash_code(CodeEmitter e, Type type, int multiplier, Customizer customizer) { if (TypeUtils.isArray(type)) { hash_array(e, type, multiplier, customizer); } else { e.swap(Type.INT_TYPE, type); e.push(multiplier); e.math(e.MUL, Type.INT_TYPE); e.swap(type, Type.INT_TYPE); if (TypeUtils.isPrimitive(type)) { hash_primitive(e, type); } else { hash_object(e, type, customizer); } e.math(e.ADD, Type.INT_TYPE); } }
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 (av != null) { av.visit(name, value); } }
public void begin_class(int version, int access, String className, Type superType, Type[] interfaces, String sourceFile) { if(!TypeUtils.isInterface(access)){ Type[] all = TypeUtils.add(interfaces, TypeUtils.getTypes(delegateIf)); super.begin_class(version, access, className, superType, all, sourceFile); declare_field(Constants.ACC_PRIVATE | Constants.ACC_TRANSIENT, DELEGATE, delegateType, null); for (int i = 0; i < delegateIf.length; i++) { Method[] methods = delegateIf[i].getMethods(); for (int j = 0; j < methods.length; j++) { if (Modifier.isAbstract(methods[j].getModifiers())) { addDelegate(methods[j]); } } } }else{ super.begin_class(version, access, className, superType, interfaces, sourceFile); } }
public CodeEmitter begin_method(int access, Signature sig, Type[] exceptions) { final CodeEmitter e = super.begin_method(access, sig, exceptions); if (sig.getName().equals(Constants.CONSTRUCTOR_NAME)) { return new CodeEmitter(e) { private boolean transformInit = true; public void visitMethodInsn(int opcode, String owner, String name, String desc) { super.visitMethodInsn(opcode, owner, name, desc); if (transformInit && opcode == Constants.INVOKESPECIAL) { load_this(); new_instance(delegateType); dup(); load_this(); invoke_constructor(delegateType, CSTRUCT_OBJECT); putfield(DELEGATE); transformInit = false; } } }; } return e; }
private void setByIndex(final String[] names, final int[] indexes) throws Exception { final CodeEmitter e = super.begin_method(Constants.ACC_PUBLIC, PROVIDER_SET_BY_INDEX, null); e.load_this(); e.load_arg(1); e.load_arg(0); e.process_switch(indexes, new ProcessSwitchCallback() { public void processCase(int key, Label end) throws Exception { Type type = (Type)fields.get(names[key]); e.unbox(type); e.putfield(names[key]); e.return_value(); } public void processDefault() throws Exception { e.throw_exception(ILLEGAL_ARGUMENT_EXCEPTION, "Unknown field index"); } }); e.end_method(); }
private void getByIndex(final String[] names, final int[] indexes) throws Exception { final CodeEmitter e = super.begin_method(Constants.ACC_PUBLIC, PROVIDER_GET_BY_INDEX, null); e.load_this(); e.load_arg(0); e.process_switch(indexes, new ProcessSwitchCallback() { public void processCase(int key, Label end) throws Exception { Type type = (Type)fields.get(names[key]); e.getfield(names[key]); e.box(type); e.return_value(); } public void processDefault() throws Exception { e.throw_exception(ILLEGAL_ARGUMENT_EXCEPTION, "Unknown field index"); } }); e.end_method(); }
private void getField(String[] names) throws Exception { final CodeEmitter e = begin_method(Constants.ACC_PUBLIC, PROVIDER_GET, null); e.load_this(); e.load_arg(0); EmitUtils.string_switch(e, names, Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() { public void processCase(Object key, Label end) { Type type = (Type)fields.get(key); e.getfield((String)key); e.box(type); e.return_value(); } public void processDefault() { e.throw_exception(ILLEGAL_ARGUMENT_EXCEPTION, "Unknown field name"); } }); e.end_method(); }
public CodeEmitter begin_method(int access, final Signature sig, final Type[] exceptions) { CodeEmitter e = super.begin_method(access, sig, exceptions); if (TypeUtils.isAbstract(access) || sig.equals(Constants.SIG_STATIC)) { return e; } return new CodeEmitter(e) { private Block handler; /* init */ { handler = begin_block(); } public void visitMaxs(int maxStack, int maxLocals) { handler.end(); EmitUtils.wrap_undeclared_throwable(this, handler, exceptions, wrapper); super.visitMaxs(maxStack, maxLocals); } }; }
private void generateGet(Class type, final Map getters) { final CodeEmitter e = begin_method(Constants.ACC_PUBLIC, BEAN_MAP_GET, null); e.load_arg(0); e.checkcast(Type.getType(type)); e.load_arg(1); e.checkcast(Constants.TYPE_STRING); EmitUtils.string_switch(e, getNames(getters), Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() { public void processCase(Object key, Label end) { PropertyDescriptor pd = (PropertyDescriptor)getters.get(key); MethodInfo method = ReflectUtils.getMethodInfo(pd.getReadMethod()); e.invoke(method); e.box(method.getSignature().getReturnType()); e.return_value(); } public void processDefault() { e.aconst_null(); e.return_value(); } }); e.end_method(); }
public void visitLdcInsn(final Object cst) { buf.setLength(0); buf.append(tab2).append("LDC "); if (cst instanceof String) { AbstractVisitor.appendString(buf, (String) cst); } else if (cst instanceof Type) { buf.append(((Type) cst).getDescriptor()).append(".class"); } else { buf.append(cst); } buf.append('\n'); text.add(buf.toString()); if (mv != null) { mv.visitLdcInsn(cst); } }
public void generateClass(ClassVisitor v) throws Exception { int size = props.size(); String[] names = (String[])props.keySet().toArray(new String[size]); Type[] types = new Type[size]; for (int i = 0; i < size; i++) { types[i] = (Type)props.get(names[i]); } ClassEmitter ce = new ClassEmitter(v); ce.begin_class(Constants.V1_2, Constants.ACC_PUBLIC, getClassName(), superclass != null ? Type.getType(superclass) : Constants.TYPE_OBJECT, null, null); EmitUtils.null_constructor(ce); EmitUtils.add_properties(ce, names, types); ce.end_class(); }
private void generateGet(final Class target, final Method[] getters) { CodeEmitter e = begin_method(Constants.ACC_PUBLIC, GET_PROPERTY_VALUES, null); if (getters.length >= 0) { e.load_arg(0); e.checkcast(Type.getType(target)); Local bean = e.make_local(); e.store_local(bean); for (int i = 0; i < getters.length; i++) { if (getters[i] != null) { MethodInfo getter = ReflectUtils.getMethodInfo(getters[i]); e.load_arg(1); e.push(i); e.load_local(bean); e.invoke(getter); e.box(getter.getSignature().getReturnType()); e.aastore(); } } } e.return_value(); e.end_method(); }
public void generateClass(ClassVisitor v) throws Exception { ClassEmitter ce = new ClassEmitter(v); ce.begin_class(Constants.V1_2, Constants.ACC_PUBLIC | Constants.ACC_INTERFACE, getClassName(), null, null, Constants.SOURCE_FILE); for (Iterator it = signatures.keySet().iterator(); it.hasNext();) { Signature sig = (Signature)it.next(); Type[] exceptions = (Type[])signatures.get(sig); ce.begin_method(Constants.ACC_PUBLIC | Constants.ACC_ABSTRACT, sig, exceptions).end_method(); } ce.end_class(); }
private static void hash_object(CodeEmitter e, Type type, Customizer customizer) { // (f == null) ? 0 : f.hashCode(); Label skip = e.make_label(); Label end = e.make_label(); e.dup(); e.ifnull(skip); if (customizer != null) { customizer.customize(e, type); } e.invoke_virtual(Constants.TYPE_OBJECT, HASH_CODE); e.goTo(end); e.mark(skip); e.pop(); e.push(0); e.mark(end); }
private static Type determineType(Class callbackType) { Class cur = null; for (int i = 0; i < CALLBACKS.length; i++) { CallbackInfo info = CALLBACKS[i]; if (info.cls.isAssignableFrom(callbackType)) { if (cur != null) { throw new IllegalStateException("Callback implements both " + cur + " and " + info.cls); } cur = info.cls; } } if (cur == null) { throw new IllegalStateException("Unknown callback type " + callbackType); } return Type.getType(cur); }
private static void load_class_helper(CodeEmitter e, final Type type) { if (e.isStaticHook()) { // have to fall back on non-optimized load e.push(TypeUtils.emulateClassGetName(type)); e.invoke_static(Constants.TYPE_CLASS, FOR_NAME); } else { ClassEmitter ce = e.getClassEmitter(); String typeName = TypeUtils.emulateClassGetName(type); // TODO: can end up with duplicated field names when using chained transformers; incorporate static hook # somehow String fieldName = "CGLIB$load_class$" + TypeUtils.escapeType(typeName); if (!ce.isFieldDeclared(fieldName)) { ce.declare_field(Constants.PRIVATE_FINAL_STATIC, fieldName, Constants.TYPE_CLASS, null); CodeEmitter hook = ce.getStaticHook(); hook.push(typeName); hook.invoke_static(Constants.TYPE_CLASS, FOR_NAME); hook.putstatic(ce.getClassType(), fieldName, Constants.TYPE_CLASS); } e.getfield(fieldName); } }
private void generateConstructor(Object[] arrays) { CodeEmitter e = begin_method(Constants.ACC_PUBLIC, CSTRUCT_OBJECT_ARRAY, null); e.load_this(); e.super_invoke_constructor(); e.load_this(); e.load_arg(0); e.super_putfield("a", Constants.TYPE_OBJECT_ARRAY); for (int i = 0; i < arrays.length; i++) { Type type = Type.getType(arrays[i].getClass()); declare_field(Constants.ACC_PRIVATE, getFieldName(i), type, null); e.load_this(); e.load_arg(0); e.push(i); e.aaload(); e.checkcast(type); e.putfield(getFieldName(i)); } e.return_value(); e.end_method(); }
public static Type getBoxedType(Type type) { switch (type.getSort()) { case Type.CHAR: return Constants.TYPE_CHARACTER; case Type.BOOLEAN: return Constants.TYPE_BOOLEAN; case Type.DOUBLE: return Constants.TYPE_DOUBLE; case Type.FLOAT: return Constants.TYPE_FLOAT; case Type.LONG: return Constants.TYPE_LONG; case Type.INT: return Constants.TYPE_INTEGER; case Type.SHORT: return Constants.TYPE_SHORT; case Type.BYTE: return Constants.TYPE_BYTE; default: return type; } }
public static Type getUnboxedType(Type type) { if (Constants.TYPE_INTEGER.equals(type)) { return Type.INT_TYPE; } else if (Constants.TYPE_BOOLEAN.equals(type)) { return Type.BOOLEAN_TYPE; } else if (Constants.TYPE_DOUBLE.equals(type)) { return Type.DOUBLE_TYPE; } else if (Constants.TYPE_LONG.equals(type)) { return Type.LONG_TYPE; } else if (Constants.TYPE_CHARACTER.equals(type)) { return Type.CHAR_TYPE; } else if (Constants.TYPE_BYTE.equals(type)) { return Type.BYTE_TYPE; } else if (Constants.TYPE_FLOAT.equals(type)) { return Type.FLOAT_TYPE; } else if (Constants.TYPE_SHORT.equals(type)) { return Type.SHORT_TYPE; } else { return type; } }
private static void hash_primitive(CodeEmitter e, Type type) { switch (type.getSort()) { case Type.BOOLEAN: // f ? 0 : 1 e.push(1); e.math(e.XOR, Type.INT_TYPE); break; case Type.FLOAT: // Float.floatToIntBits(f) e.invoke_static(Constants.TYPE_FLOAT, FLOAT_TO_INT_BITS); break; case Type.DOUBLE: // Double.doubleToLongBits(f), hash_code(Long.TYPE) e.invoke_static(Constants.TYPE_DOUBLE, DOUBLE_TO_LONG_BITS); // fall through case Type.LONG: hash_long(e); } }
public Value newOperation(final AbstractInsnNode insn) { int size; switch (insn.getOpcode()) { case LCONST_0: case LCONST_1: case DCONST_0: case DCONST_1: size = 2; break; case LDC: Object cst = ((LdcInsnNode) insn).cst; size = cst instanceof Long || cst instanceof Double ? 2 : 1; break; case GETSTATIC: size = Type.getType(((FieldInsnNode) insn).desc).getSize(); break; default: size = 1; } return new SourceValue(size, insn); }
/** * Process an array on the stack. Assumes the top item on the stack * is an array of the specified type. For each element in the array, * puts the element on the stack and triggers the callback. * @param type the type of the array (type.isArray() must be true) * @param callback the callback triggered for each element */ public static void process_array(CodeEmitter e, Type type, ProcessArrayCallback callback) { Type componentType = TypeUtils.getComponentType(type); Local array = e.make_local(); Local loopvar = e.make_local(Type.INT_TYPE); Label loopbody = e.make_label(); Label checkloop = e.make_label(); e.store_local(array); e.push(0); e.store_local(loopvar); e.goTo(checkloop); e.mark(loopbody); e.load_local(array); e.load_local(loopvar); e.array_load(componentType); callback.processElement(componentType); e.iinc(loopvar, 1); e.mark(checkloop); e.load_local(loopvar); e.load_local(array); e.arraylength(); e.if_icmp(e.LT, loopbody); }
private static void shrinkStringBuffer(CodeEmitter e, int amt) { e.dup(); e.dup(); e.invoke_virtual(Constants.TYPE_STRING_BUFFER, LENGTH); e.push(amt); e.math(e.SUB, Type.INT_TYPE); e.invoke_virtual(Constants.TYPE_STRING_BUFFER, SET_LENGTH); }
public static void push_object(CodeEmitter e, Object obj) { if (obj == null) { e.aconst_null(); } else { Class type = obj.getClass(); if (type.isArray()) { push_array(e, (Object[])obj); } else if (obj instanceof String) { e.push((String)obj); } else if (obj instanceof Type) { load_class(e, (Type)obj); } else if (obj instanceof Class) { load_class(e, Type.getType((Class)obj)); } else if (obj instanceof BigInteger) { e.new_instance(Constants.TYPE_BIG_INTEGER); e.dup(); e.push(obj.toString()); e.invoke_constructor(Constants.TYPE_BIG_INTEGER); } else if (obj instanceof BigDecimal) { e.new_instance(Constants.TYPE_BIG_DECIMAL); e.dup(); e.push(obj.toString()); e.invoke_constructor(Constants.TYPE_BIG_DECIMAL); } else { throw new IllegalArgumentException("unknown type: " + obj.getClass()); } } }
private static Signature readCallbackSig(Type type) { Type remap = remap(type); return new Signature("read" + callbackName(remap), remap, new Type[]{ Constants.TYPE_OBJECT, Constants.TYPE_STRING, remap }); }
/** Creates a new instance of AddDelegateTransformer */ public AddDelegateTransformer(Class delegateIf[], Class delegateImpl) { try { delegateImpl.getConstructor(new Class[]{ Object.class }); this.delegateIf = delegateIf; this.delegateImpl = delegateImpl; delegateType = Type.getType(delegateImpl); } catch (NoSuchMethodException e) { throw new CodeGenerationException(e); } }
public AddStaticInitTransformer(Method classInit) { info = ReflectUtils.getMethodInfo(classInit); if (!TypeUtils.isStatic(info.getModifiers())) { throw new IllegalArgumentException(classInit + " is not static"); } Type[] types = info.getSignature().getArgumentTypes(); if (types.length != 1 || !types[0].equals(Constants.TYPE_CLASS) || !info.getSignature().getReturnType().equals(Type.VOID_TYPE)) { throw new IllegalArgumentException(classInit + " illegal signature"); } }
public void begin_class(int version, int access, String className, Type superType, Type[] interfaces, String sourceFile) { if (!TypeUtils.isAbstract(access)) { interfaces = TypeUtils.add(interfaces, FIELD_PROVIDER); } this.access = access; fields = new HashMap(); super.begin_class(version, access, className, superType, interfaces, sourceFile); }
public void declare_field(int access, String name, Type type, Object value) { super.declare_field(access, name, type, value); if (!TypeUtils.isStatic(access)) { fields.put(name, type); } }
protected Value getElementValue(final Value objectArrayValue) throws AnalyzerException { Type arrayType = ((BasicValue) 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"); }
public CodeEmitter begin_method(int access, Signature sig, Type[] exceptions) { final CodeEmitter emitter = super.begin_method(access, sig, exceptions); if (sig.getName().equals(Constants.CONSTRUCTOR_NAME)) { return new CodeEmitter(emitter) { public void visitInsn(int opcode) { if (opcode == Constants.RETURN) { load_this(); invoke(info); } super.visitInsn(opcode); } }; } return emitter; }
public Value naryOperation(final AbstractInsnNode insn, final List values) { int size; if (insn.getOpcode() == MULTIANEWARRAY) { size = 1; } else { size = Type.getReturnType(((MethodInsnNode) insn).desc).getSize(); } return new SourceValue(size, insn); }
protected boolean isAssignableFrom(final Type t, final Type u) { if (t.equals(u)) { return true; } if (currentClass != null && t.equals(currentClass)) { if (getSuperClass(u) == null) { return false; } else { return isAssignableFrom(t, getSuperClass(u)); } } if (currentClass != null && u.equals(currentClass)) { if (isAssignableFrom(t, currentSuperClass)) { return true; } if (currentClassInterfaces != null) { for (int i = 0; i < currentClassInterfaces.size(); ++i) { Type v = (Type) currentClassInterfaces.get(i); if (isAssignableFrom(t, v)) { return true; } } } return false; } return getClass(t).isAssignableFrom(getClass(u)); }
public Object newInstance(String type, String[] interfaces, CallbackFilter filter, Type[] callbackTypes, boolean useFactory, boolean interceptDuringConstruction, Long serialVersionUID);
public static void add_properties(ClassEmitter ce, String[] names, Type[] types) { for (int i = 0; i < names.length; i++) { String fieldName = "$cglib_prop_" + names[i]; ce.declare_field(Constants.ACC_PRIVATE, fieldName, types[i], null); EmitUtils.add_property(ce, names[i], types[i], fieldName); } }
private void emitNewInstanceMultiarg(ClassEmitter ce, List constructors) { final CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, MULTIARG_NEW_INSTANCE, null); e.load_arg(2); e.invoke_static_this(SET_THREAD_CALLBACKS); e.new_instance_this(); e.dup(); e.load_arg(0); EmitUtils.constructor_switch(e, constructors, new ObjectSwitchCallback() { public void processCase(Object key, Label end) { MethodInfo constructor = (MethodInfo)key; Type types[] = constructor.getSignature().getArgumentTypes(); for (int i = 0; i < types.length; i++) { e.load_arg(1); e.push(i); e.aaload(); e.unbox(types[i]); } e.invoke_constructor_this(constructor.getSignature()); e.goTo(end); } public void processDefault() { e.throw_exception(ILLEGAL_ARGUMENT_EXCEPTION, "Constructor not found"); } }); e.aconst_null(); e.invoke_static_this(SET_THREAD_CALLBACKS); e.return_value(); e.end_method(); }
public static Type[] determineTypes(Class[] callbackTypes) { Type[] types = new Type[callbackTypes.length]; for (int i = 0; i < types.length; i++) { types[i] = determineType(callbackTypes[i]); } return types; }
public static Type[] determineTypes(Callback[] callbacks) { Type[] types = new Type[callbacks.length]; for (int i = 0; i < types.length; i++) { types[i] = determineType(callbacks[i]); } return types; }
private static CallbackGenerator getGenerator(Type callbackType) { for (int i = 0; i < CALLBACKS.length; i++) { CallbackInfo info = CALLBACKS[i]; if (info.type.equals(callbackType)) { return info.generator; } } throw new IllegalStateException("Unknown callback type " + callbackType); }