[FIX] Сериализация short, byte, char, boolean

This commit is contained in:
Zaxar163 2020-01-30 14:50:37 +01:00
parent d813e714da
commit 7b1ddf5577
No known key found for this signature in database
GPG key ID: 1FE4F2E1F053831B

View file

@ -21,14 +21,11 @@ public InjectClassAcceptor(Map<String, Object> values) {
this.values = values; this.values = values;
} }
private static final List<Class<?>> primitiveClasses = Arrays.asList(java.lang.Boolean.class, java.lang.Character.class, private static final List<Class<?>> primitiveLDCClasses = Arrays.asList(java.lang.Integer.class, java.lang.Long.class,
java.lang.Byte.class, java.lang.Short.class, java.lang.Integer.class, java.lang.Long.class,
java.lang.Float.class, java.lang.Double.class, java.lang.String.class); java.lang.Float.class, java.lang.Double.class, java.lang.String.class);
private static final String INJECTED_FIELD_DESC = Type.getDescriptor(LauncherInject.class); private static final String INJECTED_FIELD_DESC = Type.getDescriptor(LauncherInject.class);
private static final String INJECTED_CONSTRUCTOR_DESC = Type.getDescriptor(LauncherInjectionConstructor.class); private static final String INJECTED_CONSTRUCTOR_DESC = Type.getDescriptor(LauncherInjectionConstructor.class);
private static final List<String> primitiveDescriptors = Arrays.asList(Type.INT_TYPE.getDescriptor(), private static final List<String> primitiveLDCDescriptors = Arrays.asList(Type.INT_TYPE.getDescriptor(), Type.DOUBLE_TYPE.getDescriptor(),
Type.VOID_TYPE.getDescriptor(), Type.BOOLEAN_TYPE.getDescriptor(), Type.BYTE_TYPE.getDescriptor(),
Type.CHAR_TYPE.getDescriptor(), Type.SHORT_TYPE.getDescriptor(), Type.DOUBLE_TYPE.getDescriptor(),
Type.FLOAT_TYPE.getDescriptor(), Type.LONG_TYPE.getDescriptor(), Type.getDescriptor(String.class)); Type.FLOAT_TYPE.getDescriptor(), Type.LONG_TYPE.getDescriptor(), Type.getDescriptor(String.class));
private static void visit(ClassNode classNode, Map<String, Object> values) { private static void visit(ClassNode classNode, Map<String, Object> values) {
@ -75,7 +72,7 @@ public void visit(final String name, final Object value) {
} }
Object value = values.get(valueName.get()); Object value = values.get(valueName.get());
if ((field.access & Opcodes.ACC_STATIC) != 0) { if ((field.access & Opcodes.ACC_STATIC) != 0) {
if (primitiveDescriptors.contains(field.desc) && primitiveClasses.contains(value.getClass())) { if (primitiveLDCDescriptors.contains(field.desc) && primitiveLDCClasses.contains(value.getClass())) {
field.value = value; field.value = value;
return; return;
} }
@ -123,20 +120,47 @@ public void visit(final String name, final Object value) {
serializers.put(List.class, new ListSerializer()); serializers.put(List.class, new ListSerializer());
serializers.put(Map.class, new MapSerializer()); serializers.put(Map.class, new MapSerializer());
serializers.put(byte[].class, new ByteArraySerializer()); serializers.put(byte[].class, new ByteArraySerializer());
serializers.put(Short.class, serializerClass(Opcodes.I2S));
serializers.put(Byte.class, serializerClass(Opcodes.I2B));
serializers.put(Boolean.class, (Serializer<Boolean>) e -> {
InsnList ret = new InsnList();
ret.add(new InsnNode(e ? Opcodes.ICONST_1 : Opcodes.ICONST_0));
return ret;
});
serializers.put(Character.class, (Serializer<Character>) e -> {
InsnList ret = new InsnList();
ret.add(NodeUtils.push((int) e.charValue()));
ret.add(new InsnNode(Opcodes.I2C));
return ret;
});
} }
private static Serializer<?> serializerClass(int opcode) {
return new Serializer<Number>() {
@Override
public InsnList serialize(Number value) {
InsnList ret = new InsnList();
ret.add(NodeUtils.push(((Number) value).intValue()));
ret.add(new InsnNode(opcode));
return ret;
}
};
}
@FunctionalInterface
private interface Serializer<T> { private interface Serializer<T> {
InsnList serialize(T value); InsnList serialize(T value);
} }
@SuppressWarnings("unchecked") @SuppressWarnings({ "unchecked", "rawtypes" })
private static InsnList serializeValue(Object value) { private static InsnList serializeValue(Object value) {
if (value == null) { if (value == null) {
InsnList insnList = new InsnList(); InsnList insnList = new InsnList();
insnList.add(new InsnNode(Opcodes.ACONST_NULL)); insnList.add(new InsnNode(Opcodes.ACONST_NULL));
return insnList; return insnList;
} }
if (primitiveClasses.contains(value.getClass())) { if (primitiveLDCClasses.contains(value.getClass())) {
InsnList insnList = new InsnList(); InsnList insnList = new InsnList();
insnList.add(new LdcInsnNode(value)); insnList.add(new LdcInsnNode(value));
return insnList; return insnList;
@ -150,6 +174,7 @@ private static InsnList serializeValue(Object value) {
value.getClass())); value.getClass()));
} }
@SuppressWarnings("rawtypes")
private static class ListSerializer implements Serializer<List> { private static class ListSerializer implements Serializer<List> {
@Override @Override
@ -171,6 +196,7 @@ public InsnList serialize(List value) {
} }
} }
@SuppressWarnings("rawtypes")
private static class MapSerializer implements Serializer<Map> { private static class MapSerializer implements Serializer<Map> {
@Override @Override
@ -195,7 +221,6 @@ public InsnList serialize(Map value) {
} }
private static class ByteArraySerializer implements Serializer<byte[]> { private static class ByteArraySerializer implements Serializer<byte[]> {
@Override @Override
public InsnList serialize(byte[] value) { public InsnList serialize(byte[] value) {
InsnList insnList = new InsnList(); InsnList insnList = new InsnList();