interceptedTargetVisitor.invokeVirtual(proxyType, resolveTargetMethodDesc); interceptedTargetVisitor.returnValue(); } else {
proxyConstructorGenerator.loadThis(); proxyConstructorGenerator.loadThis(); proxyConstructorGenerator.invokeVirtual(proxyType, resolveTargetMethodDesc); proxyConstructorGenerator.putField(proxyType, FIELD_TARGET, targetType);
/** See {@link GeneratorAdapter#invokeVirtual(Type, Method)} */ public void invokeVirtual(Type owner, Method method) { adapter.invokeVirtual(owner, method); }
/** See {@link GeneratorAdapter#invokeVirtual(Type, Method)} */ public void invokeVirtual(Type owner, Method method) { adapter.invokeVirtual(owner, method); }
void visitHashMethod(GeneratorAdapter mv) { mv.invokeVirtual(STRING_TYPE, Method.getMethod("int hashCode()")); }
void loadCurrentThreadNumber() { loadStrategy(); mv.invokeVirtual(MANAGED_STRATEGY_TYPE, CURRENT_THREAD_NUMBER_METHOD); }
void visitHashMethod(GeneratorAdapter mv) { mv.invokeVirtual(STRING_TYPE, Method.getMethod("int hashCode()")); }
@Override public void onMethodExit(String name, String desc, GeneratorAdapter generatorAdapter) { // Register serializer for Schema // addDefaultSerializer(Schema.class, SchemaSerializer.class); generatorAdapter.loadThis(); generatorAdapter.push(Type.getType(Schema.class)); generatorAdapter.push(SCHEMA_SERIALIZER_TYPE); generatorAdapter.invokeVirtual(KRYO_TYPE, new Method("addDefaultSerializer", Type.VOID_TYPE, new Type[] { Type.getType(Class.class), Type.getType(Class.class)})); // Register serializer for StructuredRecord // addDefaultSerializer(StructuredRecord.class, StructuredRecordSerializer.class); generatorAdapter.loadThis(); generatorAdapter.push(Type.getType(StructuredRecord.class)); generatorAdapter.push(STRUCTURED_RECORD_SERIALIZER_TYPE); generatorAdapter.invokeVirtual(KRYO_TYPE, new Method("addDefaultSerializer", Type.VOID_TYPE, new Type[] { Type.getType(Class.class), Type.getType(Class.class)})); } });
@Override public void onMethodExit(String name, String desc, GeneratorAdapter generatorAdapter) { // Register serializer for Schema // addDefaultSerializer(Schema.class, SchemaSerializer.class); generatorAdapter.loadThis(); generatorAdapter.push(Type.getType(Schema.class)); generatorAdapter.push(SCHEMA_SERIALIZER_TYPE); generatorAdapter.invokeVirtual(KRYO_TYPE, new Method("addDefaultSerializer", Type.VOID_TYPE, new Type[] { Type.getType(Class.class), Type.getType(Class.class)})); // Register serializer for StructuredRecord // addDefaultSerializer(StructuredRecord.class, StructuredRecordSerializer.class); generatorAdapter.loadThis(); generatorAdapter.push(Type.getType(StructuredRecord.class)); generatorAdapter.push(STRUCTURED_RECORD_SERIALIZER_TYPE); generatorAdapter.invokeVirtual(KRYO_TYPE, new Method("addDefaultSerializer", Type.VOID_TYPE, new Type[] { Type.getType(Class.class), Type.getType(Class.class)})); } });
@Override public void onMethodExit(String name, String desc, GeneratorAdapter generatorAdapter) { // Register serializer for Schema // addDefaultSerializer(Schema.class, SchemaSerializer.class); generatorAdapter.loadThis(); generatorAdapter.push(Type.getType(Schema.class)); generatorAdapter.push(SCHEMA_SERIALIZER_TYPE); generatorAdapter.invokeVirtual(KRYO_TYPE, new Method("addDefaultSerializer", Type.VOID_TYPE, new Type[] { Type.getType(Class.class), Type.getType(Class.class)})); // Register serializer for StructuredRecord // addDefaultSerializer(StructuredRecord.class, StructuredRecordSerializer.class); generatorAdapter.loadThis(); generatorAdapter.push(Type.getType(StructuredRecord.class)); generatorAdapter.push(STRUCTURED_RECORD_SERIALIZER_TYPE); generatorAdapter.invokeVirtual(KRYO_TYPE, new Method("addDefaultSerializer", Type.VOID_TYPE, new Type[] { Type.getType(Class.class), Type.getType(Class.class)})); } });
/** * Generates method body for encoding enum value. * @param mg Method body generator * @param outputType * @param value * @param encoder * @param schemaLocal */ private void encodeEnum(GeneratorAdapter mg, TypeToken<?> outputType, int value, int encoder, int schemaLocal) { // Enum type might be defined by the user, hence need to preserve class loading of it preservedClasses.add(outputType.getRawType()); // encoder.writeInt(this.schema.getEnumIndex(value.name())); mg.loadArg(encoder); mg.loadArg(schemaLocal); mg.loadArg(value); mg.invokeVirtual(Type.getType(outputType.getRawType()), getMethod(String.class, "name")); mg.invokeVirtual(Type.getType(Schema.class), getMethod(int.class, "getEnumIndex", String.class)); mg.invokeInterface(Type.getType(Encoder.class), getMethod(Encoder.class, "writeInt", int.class)); mg.pop(); }
/** * Generates method body for encoding enum value. * @param mg Method body generator * @param outputType * @param value * @param encoder * @param schemaLocal */ private void encodeEnum(GeneratorAdapter mg, TypeToken<?> outputType, int value, int encoder, int schemaLocal) { // Enum type might be defined by the user, hence need to preserve class loading of it preservedClasses.add(outputType.getRawType()); // encoder.writeInt(this.schema.getEnumIndex(value.name())); mg.loadArg(encoder); mg.loadArg(schemaLocal); mg.loadArg(value); mg.invokeVirtual(Type.getType(outputType.getRawType()), getMethod(String.class, "name")); mg.invokeVirtual(Type.getType(Schema.class), getMethod(int.class, "getEnumIndex", String.class)); mg.invokeInterface(Type.getType(Encoder.class), getMethod(Encoder.class, "writeInt", int.class)); mg.pop(); }
private void invokeOnSharedVariableAccess(Method method) { loadStrategy(); loadCurrentThreadNumber(); loadNewCodeLocation(); mv.invokeVirtual(MANAGED_STRATEGY_TYPE, method); }
/** * Generates the primitive getter (getXXX) based on the field type. * @param field The reflection field object. */ private void primitiveGetter(Field field) { String typeName = field.getType().getName(); String methodName = String.format("get%c%s", Character.toUpperCase(typeName.charAt(0)), typeName.substring(1)); GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, getMethod(field.getType(), methodName, Object.class), null, new Type[0], classWriter); if (isPrivate) { // get the value using the generic Object get(Object) method and unbox the value mg.loadThis(); mg.loadArg(0); mg.invokeVirtual(Type.getObjectType(className), getMethod(Object.class, "get", Object.class)); mg.unbox(Type.getType(field.getType())); } else { // Simply access the field. mg.loadArg(0); mg.checkCast(Type.getType(field.getDeclaringClass())); mg.getField(Type.getType(field.getDeclaringClass()), field.getName(), Type.getType(field.getType())); } mg.returnValue(); mg.endMethod(); }
/** * Generates the primitive getter (getXXX) based on the field type. * @param field The reflection field object. */ private void primitiveGetter(Field field) { String typeName = field.getType().getName(); String methodName = String.format("get%c%s", Character.toUpperCase(typeName.charAt(0)), typeName.substring(1)); GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, getMethod(field.getType(), methodName, Object.class), null, new Type[0], classWriter); if (isPrivate) { // get the value using the generic Object get(Object) method and unbox the value mg.loadThis(); mg.loadArg(0); mg.invokeVirtual(Type.getObjectType(className), getMethod(Object.class, "get", Object.class)); mg.unbox(Type.getType(field.getType())); } else { // Simply access the field. mg.loadArg(0); mg.checkCast(Type.getType(field.getDeclaringClass())); mg.getField(Type.getType(field.getDeclaringClass()), field.getName(), Type.getType(field.getType())); } mg.returnValue(); mg.endMethod(); }
/** * Generates method body for encoding enum value. * @param mg Method body generator * @param outputType * @param value * @param encoder * @param schemaLocal */ private void encodeEnum(GeneratorAdapter mg, TypeToken<?> outputType, int value, int encoder, int schemaLocal) { // encoder.writeInt(this.schema.getEnumIndex(value.name())); mg.loadArg(encoder); mg.loadArg(schemaLocal); mg.loadArg(value); mg.invokeVirtual(Type.getType(outputType.getRawType()), getMethod(String.class, "name")); mg.invokeVirtual(Type.getType(Schema.class), getMethod(int.class, "getEnumIndex", String.class)); mg.invokeInterface(Type.getType(Encoder.class), getMethod(Encoder.class, "writeInt", int.class)); mg.pop(); }
/** * Generates unboxing bytecode for the passed type. An {@link Object} is expected to be on the * stack when these bytecodes are inserted. * * ASM takes a short cut when dealing with short/byte types and convert them into int rather * than short/byte types. This is not an issue on the jvm nor Android's ART but it is an issue * on Dalvik. * * @param mv the {@link GeneratorAdapter} generating a method implementation. * @param type the expected un-boxed type. */ public static void unbox(GeneratorAdapter mv, Type type) { if (type.equals(Type.SHORT_TYPE)) { mv.checkCast(NUMBER_TYPE); mv.invokeVirtual(NUMBER_TYPE, SHORT_VALUE); } else if (type.equals(Type.BYTE_TYPE)) { mv.checkCast(NUMBER_TYPE); mv.invokeVirtual(NUMBER_TYPE, BYTE_VALUE); } else { mv.unbox(type); } }
/** * Generates unboxing bytecode for the passed type. An {@link Object} is expected to be on the * stack when these bytecodes are inserted. * * ASM takes a short cut when dealing with short/byte types and convert them into int rather * than short/byte types. This is not an issue on the jvm nor Android's ART but it is an issue * on Dalvik. * * @param mv the {@link GeneratorAdapter} generating a method implementation. * @param type the expected un-boxed type. */ public static void unbox(GeneratorAdapter mv, Type type) { if (type.equals(Type.SHORT_TYPE)) { mv.checkCast(NUMBER_TYPE); mv.invokeVirtual(NUMBER_TYPE, SHORT_VALUE); } else if (type.equals(Type.BYTE_TYPE)) { mv.checkCast(NUMBER_TYPE); mv.invokeVirtual(NUMBER_TYPE, BYTE_VALUE); } else { mv.unbox(type); } }
private void invokeOnLockAcquireOrRelease(Method method) { int monitorLocal = mv.newLocal(OBJECT_TYPE); mv.dup(); mv.storeLocal(monitorLocal); loadCurrentThreadNumber(); loadNewCodeLocation(); mv.loadLocal(monitorLocal); mv.invokeVirtual(MANAGED_STRATEGY_TYPE, method); }
private static void storeExceptionResultFromThrowable(GeneratorAdapter mv, int resLocal, int iLocal) { int eLocal = mv.newLocal(THROWABLE_TYPE); mv.storeLocal(eLocal); mv.loadLocal(resLocal); mv.loadLocal(iLocal); mv.loadLocal(eLocal); mv.invokeVirtual(OBJECT_TYPE, OBJECT_GET_CLASS); mv.invokeStatic(RESULT_TYPE, RESULT_CREATE_EXCEPTION_RESULT); mv.arrayStore(RESULT_TYPE); }