Просмотр исходного кода

new: SerializableCode (fix #5)
new: ResourceUtils#text
new: ReflectUtils#getByteCode
new: IClassLoader#defineClass(bytecode)

Mariusz Sieroń 6 лет назад
Родитель
Сommit
de5bd25ef9

+ 13 - 2
assira.asm/pom.xml

@@ -9,7 +9,7 @@
     </parent>
     <groupId>net.ranides</groupId>
     <artifactId>assira.asm</artifactId>
-    <version>7.1</version>
+    <version>7.2</version>
     <packaging>jar</packaging>  
 
     <build>
@@ -60,8 +60,19 @@
         <dependency>
             <groupId>org.ow2.asm</groupId>
             <artifactId>asm</artifactId>
-            <version>7.1</version>
+            <version>7.2</version>
         </dependency>
+        <dependency>
+            <groupId>org.ow2.asm</groupId>
+            <artifactId>asm-commons</artifactId>
+            <version>7.2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.ow2.asm</groupId>
+            <artifactId>asm-util</artifactId>
+            <version>7.2</version>
+        </dependency>
+
     </dependencies>
     
 </project>

+ 0 - 109
assira.drafts/src/main/java/net/ranides/assira/functional/CodeSerializer.java

@@ -1,109 +0,0 @@
-package net.ranides.assira.functional;
-
-import net.ranides.assira.io.IOStreams;
-import net.ranides.assira.io.IOUtils;
-import net.ranides.assira.reflection.IClass;
-import net.ranides.assira.reflection.IClassLoader;
-
-import java.io.*;
-import java.util.*;
-
-public class CodeSerializer {
-
-    public static Serializable withCode(Serializable object) {
-        return new CodeWriter(new ClassWithCode(object));
-    }
-
-    private static IClassLoader LOADER = new IClassLoader("serializer", IClassLoader.getSystem()){
-
-        private final Map<String, byte[]> bytecodes = new HashMap<>();
-
-        private final Map<String, IClass<?>> loaded = new HashMap<>();
-
-        @Override
-        public IClass<?> defineClass(String name, byte[] bytecode) {
-            if(bytecodes.containsKey(name)) {
-                if (Arrays.equals(bytecode, bytecodes.get(name))) {
-                    return loaded.get(name);
-                } else {
-                    throw new IllegalArgumentException("Different bytecode!");
-                }
-            }
-            IClass<?> ic = super.defineClass(name, bytecode);
-            bytecodes.put(name, bytecode);
-            loaded.put(name, ic);
-            return ic;
-        }
-    };
-
-    private static class CodeWriter implements Serializable {
-
-        private final ClassWithCode extern;
-
-        public CodeWriter(ClassWithCode extern) {
-            this.extern = extern;
-        }
-
-        private Object readResolve() {
-            return extern.value;
-        }
-
-    }
-
-    private static class ClassWithCode implements Serializable {
-
-        private static final long serialVersionUID = 4L;
-
-        private String classname;
-
-        private byte[] bytecode;
-
-        private transient Object value;
-
-        public ClassWithCode(Object value) {
-            try {
-                Class<?> ic = value.getClass();
-                try(InputStream is = ic.getClassLoader().getResourceAsStream(ic.getName().replace('.', '/') + ".class")) {
-                    this.classname = ic.getName();
-                    this.bytecode = IOStreams.read(is);
-                    this.value = value;
-                }
-            } catch (IOException e) {
-                throw new RuntimeException(e);
-            }
-        }
-
-        private void writeObject(java.io.ObjectOutputStream out) throws IOException {
-            out.writeObject(classname);
-            out.writeObject(bytecode);
-
-            ObjectOutputStream oos = new ObjectOutputStream(out);
-            oos.writeObject(value);
-            oos.flush();
-        }
-
-        private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
-            classname = (String)in.readObject();
-            bytecode = (byte[]) in.readObject();
-            IClass<?> ic = LOADER.defineClass(classname, bytecode);
-            ObjectInputStreamWithClass oisc = new ObjectInputStreamWithClass(in, ic);
-            this.value = oisc.readObject();
-        }
-
-    }
-
-    private static class ObjectInputStreamWithClass extends ObjectInputStream {
-        private final IClass<?> clazz;
-
-        public ObjectInputStreamWithClass(InputStream in, IClass<?> clazz) throws IOException {
-            super(in);
-            this.clazz = clazz;
-        }
-
-        @SuppressWarnings("rawtypes")
-        protected Class<?> resolveClass(ObjectStreamClass classDesc) throws ClassNotFoundException, IOException {
-            return classDesc.getName().equals(clazz.name()) ? clazz.raw() : super.resolveClass(classDesc);
-        }
-    }
-
-}

Разница между файлами не показана из-за своего большого размера
+ 0 - 73
assira.drafts/src/test/java/net/ranides/assira/functional/CodeSerializerTest.java


+ 121 - 0
assira/src/main/java/net/ranides/assira/generic/SerializableCode.java

@@ -0,0 +1,121 @@
+package net.ranides.assira.generic;
+
+import net.ranides.assira.collection.HashFunction;
+import net.ranides.assira.collection.maps.CustomMap;
+import net.ranides.assira.reflection.IClass;
+import net.ranides.assira.reflection.IClassLoader;
+import net.ranides.assira.reflection.IField;
+import net.ranides.assira.reflection.util.ReflectUtils;
+
+import java.io.*;
+import java.util.Arrays;
+import java.util.Map;
+
+public abstract class SerializableCode implements Serializable {
+
+    private static final long serialVersionUID = 8L;
+
+    protected boolean writeReplace = true;
+
+    protected Object writeReplace() {
+        return writeReplace ? SerializableCode.wrap(this) : this;
+    }
+
+    public static Serializable wrap(Serializable object) {
+        return new ResolveWrapper(new CodeContainer(object));
+    }
+
+    private static class ResolveWrapper implements Serializable {
+
+        private static final long serialVersionUID = 8L;
+
+        private final CodeContainer extern;
+
+        public ResolveWrapper(CodeContainer extern) {
+            this.extern = extern;
+        }
+
+        private Object readResolve() {
+            return extern.value;
+        }
+
+    }
+
+    private static class CodeContainer implements Serializable {
+
+        private static final IField WRITE_REPLACE = IClass.typeinfo(SerializableCode.class).field("writeReplace").get().accessible();
+
+        private static final IClassLoader SYSTEM = new CSLoader("serializer", IClassLoader.getSystem());
+
+        private static final long serialVersionUID = 8L;
+
+        private byte[] bytecode;
+
+        private transient Object value;
+
+        public CodeContainer(Object value) {
+            this.bytecode = ReflectUtils.getByteCode(value.getClass());
+            this.value = value;
+        }
+
+        private void writeObject(java.io.ObjectOutputStream out) throws IOException {
+            out.writeObject(bytecode);
+
+            ObjectOutputStream substream = new ObjectOutputStream(out);
+            if(value instanceof SerializableCode) {
+                WRITE_REPLACE.set(value, false);
+                substream.writeObject(value);
+                WRITE_REPLACE.set(value, true);
+            } else {
+                substream.writeObject(value);
+            }
+            substream.flush();
+        }
+
+        private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
+            this.bytecode = (byte[]) in.readObject();
+            this.value = new CSInput(in, SYSTEM.defineClass(bytecode)).readObject();
+        }
+
+    }
+
+    private static class CSLoader extends IClassLoader {
+
+        private final Map<byte[], IClass<?>> loaded = new CustomMap<>(new HashFunction<byte[]>() {
+            @Override
+            public int hashCode(byte[] object) {
+                return Arrays.hashCode(object);
+            }
+            @Override
+            public boolean equals(byte[] a, byte[] b) {
+                return Arrays.equals(a, b);
+            }
+        });
+
+        public CSLoader(String name, ClassLoader parent) {
+            super(name, parent);
+        }
+
+        @Override
+        public IClass<?> defineClass(String name, byte[] bytecode) {
+            return loaded.computeIfAbsent(bytecode, bc -> super.defineClass(name, bytecode));
+        }
+    }
+
+
+    private static class CSInput extends ObjectInputStream {
+
+        private final IClass<?> clazz;
+
+        public CSInput(InputStream in, IClass<?> clazz) throws IOException {
+            super(in);
+            this.clazz = clazz;
+        }
+
+        @SuppressWarnings("rawtypes")
+        protected Class<?> resolveClass(ObjectStreamClass classDesc) throws ClassNotFoundException, IOException {
+            return classDesc.getName().equals(clazz.name()) ? clazz.raw() : super.resolveClass(classDesc);
+        }
+    }
+
+}

+ 9 - 0
assira/src/main/java/net/ranides/assira/io/ResourceUtils.java

@@ -17,6 +17,7 @@ import java.io.Reader;
 import java.nio.charset.Charset;
 import java.util.MissingResourceException;
 import net.ranides.assira.reflection.util.ClassUtils;
+import net.ranides.assira.text.IOStrings;
 
 /**
  *
@@ -61,4 +62,12 @@ public final class ResourceUtils {
         return new InputStreamReader(stream(loader, resource), charset);
     }
 
+    public static String text(String resource, Charset charset) throws IOException {
+        return IOStrings.read(reader(resource, charset));
+    }
+
+    public static String text(ClassLoader loader, String resource, Charset charset) throws IOException {
+        return IOStrings.read(reader(loader, resource, charset));
+    }
+
 }

+ 7 - 0
assira/src/main/java/net/ranides/assira/reflection/IClassLoader.java

@@ -1,5 +1,7 @@
 package net.ranides.assira.reflection;
 
+import net.ranides.asm.ClassReader;
+
 import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.concurrent.ConcurrentHashMap;
@@ -54,4 +56,9 @@ public class IClassLoader extends ClassLoader {
         return IClass.typeinfo(defineClass(name, bytecode, 0, bytecode.length));
     }
 
+    public IClass<?> defineClass(byte[] bytecode) {
+        String classname = new ClassReader(bytecode).getClassName().replace('/', '.');
+        return defineClass(classname, bytecode);
+    }
+
 }

+ 21 - 0
assira/src/main/java/net/ranides/assira/reflection/util/ReflectUtils.java

@@ -6,6 +6,7 @@
  */
 package net.ranides.assira.reflection.util;
 
+import net.ranides.assira.io.IOStreams;
 import net.ranides.assira.io.PathUtils;
 import net.ranides.assira.system.RuntimeUtils;
 import net.ranides.assira.text.Charsets;
@@ -15,6 +16,7 @@ import net.ranides.assira.trace.ExceptionUtils;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.UncheckedIOException;
 import java.lang.reflect.AccessibleObject;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
@@ -69,6 +71,25 @@ public final class ReflectUtils {
         return field;
     }
 
+    public static byte[] getByteCode(String classname) {
+        return readByteCode(ClassUtils.loader(), classname);
+    }
+
+    public static byte[] getByteCode(Class<?> clazz) {
+        return readByteCode(clazz.getClassLoader(), clazz.getName());
+    }
+
+    private static byte[] readByteCode(ClassLoader loader, String classname){
+        try {
+            String name = classname.replace('.', '/') + ".class";
+            try (InputStream istream = loader.getResourceAsStream(name)) {
+                return IOStreams.read(istream);
+            }
+        } catch (IOException cause) {
+            throw new UncheckedIOException(cause);
+        }
+    }
+
     /**
      * Zwraca zawartość pliku źródłowego, w którym zapisana jest podana klasa.
      * Oczywiście, to nie działa idealnie dla klas, które nie mają pliku źródłowego

+ 104 - 0
assira/src/test/java/net/ranides/assira/generic/SerializableCodeTest.java

@@ -0,0 +1,104 @@
+package net.ranides.assira.generic;
+
+import lombok.Data;
+import net.ranides.assira.io.ResourceUtils;
+import net.ranides.assira.text.FormatHex;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.nio.charset.StandardCharsets;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class SerializableCodeTest {
+
+//    @Ignore("manual")
+//    @Test
+//    public void demo() throws IOException {
+//        System.out.println(FormatHex.format(SerializationUtils.write(SerializableCode.wrap(new Adder1(7)))));
+//
+//        System.out.println(FormatHex.format(SerializationUtils.write(SerializableCode.wrap(new Multiplier1(5)))));
+//
+//        System.out.println(FormatHex.format(SerializationUtils.write(new Divider1(3))));
+//
+//    }
+
+    @Test
+    public void demo() throws IOException {
+        byte[] add = SerializationUtils.write(SerializableCode.wrap(new Adder2(7)));
+        byte[] mul = SerializationUtils.write(SerializableCode.wrap(new Multiplier2(5)));
+        byte[] div = SerializationUtils.write(SerializableCode.wrap(new Divider2(5)));
+
+        assertNotNull(add);
+        assertNotNull(mul);
+        assertNotNull(div);
+    }
+
+
+    @Test
+    public void fromBytes() throws IOException {
+        Operator add = SerializationUtils.read(Operator.class, readFromFile("bytecode/add.txt"));
+        Operator mul = SerializationUtils.read(Operator.class, readFromFile("bytecode/mul.txt"));
+        Operator div1 = SerializationUtils.read(Operator.class, readFromFile("bytecode/div.txt"));
+        Operator div2 = SerializationUtils.read(Operator.class, readFromFile("bytecode/div.txt"));
+
+        assertEquals("net.ranides.assira.generic.SerializableCodeTest$Adder1", add.getClass().getName());
+        assertEquals("net.ranides.assira.generic.SerializableCodeTest$Multiplier1", mul.getClass().getName());
+        assertEquals("net.ranides.assira.generic.SerializableCodeTest$Divider1", div1.getClass().getName());
+        assertEquals("net.ranides.assira.generic.SerializableCodeTest$Divider1", div2.getClass().getName());
+
+        assertEquals(22, add.apply(15));
+        assertEquals(75, mul.apply(15));
+        assertEquals(5, div1.apply(15));
+        assertEquals(5, div2.apply(15));
+    }
+
+    private static byte[] readFromFile(String file) throws IOException {
+        String text = ResourceUtils.text(file, StandardCharsets.US_ASCII);
+        return FormatHex.parse(text.replaceAll("//.*[\\n\\r]+", "").replaceAll("[\\n\\r]+", " "));
+    }
+
+    public interface Operator {
+
+        int apply(int x);
+
+    }
+
+    @Data
+    public static class Divider2 extends SerializableCode implements Operator {
+
+        private final int a;
+
+        @Override
+        public int apply(int x) {
+            return x / a;
+        }
+
+    }
+
+    @Data
+    public static class Adder2 implements Operator, Serializable {
+
+        private final int a;
+
+        @Override
+        public int apply(int x) {
+            return x + a;
+        }
+
+    }
+
+    @Data
+    public static class Multiplier2 implements Operator, Serializable {
+
+        private final int a;
+
+        @Override
+        public int apply(int x) {
+            return x * a;
+        }
+    }
+
+}

+ 60 - 0
assira/src/test/resources/bytecode/add.txt

@@ -0,0 +1,60 @@
+//
+//    @Data
+//    public static class Adder1 implements Operator, Serializable {
+//
+//        private final int a;
+//
+//        @Override
+//        public int apply(int x) {
+//            return x + a;
+//        }
+//
+//    }
+//
+AC ED 00 05 73 72 00 3A 6E 65 74 2E 72 61 6E 69 64 65 73 2E 61 73 73 69 72 61 2E 67 65 6E 65 72 69 63 2E 53 65 72 69 61
+6C 69 7A 61 62 6C 65 43 6F 64 65 24 52 65 73 6F 6C 76 65 57 72 61 70 70 65 72 00 00 00 00 00 00 00 08 02 00 01 4C 00 06
+65 78 74 65 72 6E 74 00 3B 4C 6E 65 74 2F 72 61 6E 69 64 65 73 2F 61 73 73 69 72 61 2F 67 65 6E 65 72 69 63 2F 53 65 72
+69 61 6C 69 7A 61 62 6C 65 43 6F 64 65 24 43 6F 64 65 43 6F 6E 74 61 69 6E 65 72 3B 78 70 73 72 00 39 6E 65 74 2E 72 61
+6E 69 64 65 73 2E 61 73 73 69 72 61 2E 67 65 6E 65 72 69 63 2E 53 65 72 69 61 6C 69 7A 61 62 6C 65 43 6F 64 65 24 43 6F
+64 65 43 6F 6E 74 61 69 6E 65 72 00 00 00 00 00 00 00 08 03 00 01 5B 00 08 62 79 74 65 63 6F 64 65 74 00 02 5B 42 78 70
+75 72 00 02 5B 42 AC F3 17 F8 06 08 54 E0 02 00 00 78 70 00 00 05 FB CA FE BA BE 00 00 00 34 00 44 09 00 03 00 2F 0A 00
+0D 00 30 07 00 32 0A 00 03 00 33 0A 00 03 00 34 07 00 35 0A 00 06 00 30 08 00 36 0A 00 06 00 37 0A 00 06 00 38 08 00 39
+0A 00 06 00 3A 07 00 3B 07 00 3C 07 00 3E 01 00 01 61 01 00 01 49 01 00 05 61 70 70 6C 79 01 00 04 28 49 29 49 01 00 04
+43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61 6C 56 61 72 69 61 62 6C 65 54 61
+62 6C 65 01 00 04 74 68 69 73 01 00 06 41 64 64 65 72 31 01 00 0C 49 6E 6E 65 72 43 6C 61 73 73 65 73 01 00 38 4C 6E 65
+74 2F 72 61 6E 69 64 65 73 2F 61 73 73 69 72 61 2F 67 65 6E 65 72 69 63 2F 53 65 72 69 61 6C 69 7A 61 62 6C 65 43 6F 64
+65 54 65 73 74 24 41 64 64 65 72 31 3B 01 00 01 78 01 00 06 3C 69 6E 69 74 3E 01 00 04 28 49 29 56 01 00 04 67 65 74 41
+01 00 03 28 29 49 01 00 06 65 71 75 61 6C 73 01 00 15 28 4C 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 3B 29 5A 01
+00 01 6F 01 00 12 4C 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 3B 01 00 05 6F 74 68 65 72 01 00 0D 53 74 61 63 6B
+4D 61 70 54 61 62 6C 65 07 00 32 01 00 08 63 61 6E 45 71 75 61 6C 01 00 08 68 61 73 68 43 6F 64 65 01 00 05 50 52 49 4D
+45 01 00 06 72 65 73 75 6C 74 01 00 08 74 6F 53 74 72 69 6E 67 01 00 14 28 29 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72
+69 6E 67 3B 01 00 0A 53 6F 75 72 63 65 46 69 6C 65 01 00 19 53 65 72 69 61 6C 69 7A 61 62 6C 65 43 6F 64 65 54 65 73 74
+2E 6A 61 76 61 0C 00 10 00 11 0C 00 1C 00 3F 07 00 40 01 00 36 6E 65 74 2F 72 61 6E 69 64 65 73 2F 61 73 73 69 72 61 2F
+67 65 6E 65 72 69 63 2F 53 65 72 69 61 6C 69 7A 61 62 6C 65 43 6F 64 65 54 65 73 74 24 41 64 64 65 72 31 0C 00 27 00 21
+0C 00 1E 00 1F 01 00 17 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 42 75 69 6C 64 65 72 01 00 1E 53 65 72 69 61 6C
+69 7A 61 62 6C 65 43 6F 64 65 54 65 73 74 2E 41 64 64 65 72 31 28 61 3D 0C 00 41 00 42 0C 00 41 00 43 01 00 01 29 0C 00
+2B 00 2C 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 01 00 38 6E 65 74 2F 72 61 6E 69 64 65 73 2F 61 73 73
+69 72 61 2F 67 65 6E 65 72 69 63 2F 53 65 72 69 61 6C 69 7A 61 62 6C 65 43 6F 64 65 54 65 73 74 24 4F 70 65 72 61 74 6F
+72 01 00 08 4F 70 65 72 61 74 6F 72 01 00 14 6A 61 76 61 2F 69 6F 2F 53 65 72 69 61 6C 69 7A 61 62 6C 65 01 00 03 28 29
+56 01 00 2F 6E 65 74 2F 72 61 6E 69 64 65 73 2F 61 73 73 69 72 61 2F 67 65 6E 65 72 69 63 2F 53 65 72 69 61 6C 69 7A 61
+62 6C 65 43 6F 64 65 54 65 73 74 01 00 06 61 70 70 65 6E 64 01 00 2D 28 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E
+67 3B 29 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 42 75 69 6C 64 65 72 3B 01 00 1C 28 49 29 4C 6A 61 76 61 2F
+6C 61 6E 67 2F 53 74 72 69 6E 67 42 75 69 6C 64 65 72 3B 00 21 00 03 00 0D 00 02 00 0E 00 0F 00 01 00 12 00 10 00 11 00
+00 00 07 00 01 00 12 00 13 00 01 00 14 00 00 00 3B 00 02 00 02 00 00 00 07 1B 2A B4 00 01 60 AC 00 00 00 02 00 15 00 00
+00 06 00 01 00 00 00 56 00 16 00 00 00 16 00 02 00 00 00 07 00 17 00 1A 00 00 00 00 00 07 00 1B 00 11 00 01 00 01 00 1C
+00 1D 00 01 00 14 00 00 00 3E 00 02 00 02 00 00 00 0A 2A B7 00 02 2A 1B B5 00 01 B1 00 00 00 02 00 15 00 00 00 06 00 01
+00 00 00 4F 00 16 00 00 00 16 00 02 00 00 00 0A 00 17 00 1A 00 00 00 00 00 0A 00 10 00 11 00 01 00 01 00 1E 00 1F 00 01
+00 14 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 01 AC 00 00 00 02 00 15 00 00 00 06 00 01 00 00 00 52 00 16 00 00 00
+0C 00 01 00 00 00 05 00 17 00 1A 00 00 00 01 00 20 00 21 00 01 00 14 00 00 00 7D 00 02 00 03 00 00 00 2E 2B 2A A6 00 05
+04 AC 2B C1 00 03 9A 00 05 03 AC 2B C0 00 03 4D 2C 2A B6 00 04 9A 00 05 03 AC 2A B6 00 05 2C B6 00 05 9F 00 05 03 AC 04
+AC 00 00 00 03 00 15 00 00 00 06 00 01 00 00 00 4F 00 16 00 00 00 20 00 03 00 00 00 2E 00 17 00 1A 00 00 00 00 00 2E 00
+22 00 23 00 01 00 15 00 19 00 24 00 1A 00 02 00 25 00 00 00 0B 00 04 07 08 FC 00 0E 07 00 26 0C 00 04 00 27 00 21 00 01
+00 14 00 00 00 39 00 01 00 02 00 00 00 05 2B C1 00 03 AC 00 00 00 02 00 15 00 00 00 06 00 01 00 00 00 4F 00 16 00 00 00
+16 00 02 00 00 00 05 00 17 00 1A 00 00 00 00 00 05 00 24 00 23 00 01 00 01 00 28 00 1F 00 01 00 14 00 00 00 4F 00 02 00
+03 00 00 00 11 10 3B 3C 04 3D 1C 10 3B 68 2A B6 00 05 60 3D 1C AC 00 00 00 02 00 15 00 00 00 06 00 01 00 00 00 4F 00 16
+00 00 00 20 00 03 00 00 00 11 00 17 00 1A 00 00 00 03 00 0E 00 29 00 11 00 01 00 05 00 0C 00 2A 00 11 00 02 00 01 00 2B
+00 2C 00 01 00 14 00 00 00 46 00 02 00 01 00 00 00 1C BB 00 06 59 B7 00 07 12 08 B6 00 09 2A B6 00 05 B6 00 0A 12 0B B6
+00 09 B6 00 0C B0 00 00 00 02 00 15 00 00 00 06 00 01 00 00 00 4F 00 16 00 00 00 0C 00 01 00 00 00 1C 00 17 00 1A 00 00
+00 02 00 2D 00 00 00 02 00 2E 00 19 00 00 00 12 00 02 00 03 00 31 00 18 00 09 00 0E 00 31 00 3D 06 09 77 53 AC ED 00 05
+73 72 00 36 6E 65 74 2E 72 61 6E 69 64 65 73 2E 61 73 73 69 72 61 2E 67 65 6E 65 72 69 63 2E 53 65 72 69 61 6C 69 7A 61
+62 6C 65 43 6F 64 65 54 65 73 74 24 41 64 64 65 72 31 F8 BA 5C 1E 1D 21 9D B8 02 00 01 49 00 01 61 78 70 00 00 00 07 78

+ 63 - 0
assira/src/test/resources/bytecode/div.txt

@@ -0,0 +1,63 @@
+//
+//    @Data
+//    public static class Divider1 extends SerializableCode implements Operator {
+//
+//        private final int a;
+//
+//        @Override
+//        public int apply(int x) {
+//            return x / a;
+//        }
+//
+//    }
+//
+AC ED 00 05 73 72 00 3A 6E 65 74 2E 72 61 6E 69 64 65 73 2E 61 73 73 69 72 61 2E 67 65 6E 65 72 69 63 2E 53 65 72 69 61
+6C 69 7A 61 62 6C 65 43 6F 64 65 24 52 65 73 6F 6C 76 65 57 72 61 70 70 65 72 00 00 00 00 00 00 00 08 02 00 01 4C 00 06
+65 78 74 65 72 6E 74 00 3B 4C 6E 65 74 2F 72 61 6E 69 64 65 73 2F 61 73 73 69 72 61 2F 67 65 6E 65 72 69 63 2F 53 65 72
+69 61 6C 69 7A 61 62 6C 65 43 6F 64 65 24 43 6F 64 65 43 6F 6E 74 61 69 6E 65 72 3B 78 70 73 72 00 39 6E 65 74 2E 72 61
+6E 69 64 65 73 2E 61 73 73 69 72 61 2E 67 65 6E 65 72 69 63 2E 53 65 72 69 61 6C 69 7A 61 62 6C 65 43 6F 64 65 24 43 6F
+64 65 43 6F 6E 74 61 69 6E 65 72 00 00 00 00 00 00 00 08 03 00 01 5B 00 08 62 79 74 65 63 6F 64 65 74 00 02 5B 42 78 70
+75 72 00 02 5B 42 AC F3 17 F8 06 08 54 E0 02 00 00 78 70 00 00 06 02 CA FE BA BE 00 00 00 34 00 42 09 00 03 00 2E 0A 00
+0D 00 2F 07 00 31 0A 00 03 00 32 0A 00 03 00 33 07 00 34 0A 00 06 00 2F 08 00 35 0A 00 06 00 36 0A 00 06 00 37 08 00 38
+0A 00 06 00 39 07 00 3A 07 00 3B 01 00 01 61 01 00 01 49 01 00 05 61 70 70 6C 79 01 00 04 28 49 29 49 01 00 04 43 6F 64
+65 01 00 0F 4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61 6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65
+01 00 04 74 68 69 73 01 00 08 44 69 76 69 64 65 72 31 01 00 0C 49 6E 6E 65 72 43 6C 61 73 73 65 73 01 00 3A 4C 6E 65 74
+2F 72 61 6E 69 64 65 73 2F 61 73 73 69 72 61 2F 67 65 6E 65 72 69 63 2F 53 65 72 69 61 6C 69 7A 61 62 6C 65 43 6F 64 65
+54 65 73 74 24 44 69 76 69 64 65 72 31 3B 01 00 01 78 01 00 06 3C 69 6E 69 74 3E 01 00 04 28 49 29 56 01 00 04 67 65 74
+41 01 00 03 28 29 49 01 00 06 65 71 75 61 6C 73 01 00 15 28 4C 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 3B 29 5A
+01 00 01 6F 01 00 12 4C 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 3B 01 00 05 6F 74 68 65 72 01 00 0D 53 74 61 63
+6B 4D 61 70 54 61 62 6C 65 07 00 31 01 00 08 63 61 6E 45 71 75 61 6C 01 00 08 68 61 73 68 43 6F 64 65 01 00 05 50 52 49
+4D 45 01 00 06 72 65 73 75 6C 74 01 00 08 74 6F 53 74 72 69 6E 67 01 00 14 28 29 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74
+72 69 6E 67 3B 01 00 0A 53 6F 75 72 63 65 46 69 6C 65 01 00 19 53 65 72 69 61 6C 69 7A 61 62 6C 65 43 6F 64 65 54 65 73
+74 2E 6A 61 76 61 0C 00 0F 00 10 0C 00 1B 00 3D 07 00 3E 01 00 38 6E 65 74 2F 72 61 6E 69 64 65 73 2F 61 73 73 69 72 61
+2F 67 65 6E 65 72 69 63 2F 53 65 72 69 61 6C 69 7A 61 62 6C 65 43 6F 64 65 54 65 73 74 24 44 69 76 69 64 65 72 31 0C 00
+26 00 20 0C 00 1D 00 1E 01 00 17 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 42 75 69 6C 64 65 72 01 00 20 53 65 72
+69 61 6C 69 7A 61 62 6C 65 43 6F 64 65 54 65 73 74 2E 44 69 76 69 64 65 72 31 28 61 3D 0C 00 3F 00 40 0C 00 3F 00 41 01
+00 01 29 0C 00 2A 00 2B 01 00 2B 6E 65 74 2F 72 61 6E 69 64 65 73 2F 61 73 73 69 72 61 2F 67 65 6E 65 72 69 63 2F 53 65
+72 69 61 6C 69 7A 61 62 6C 65 43 6F 64 65 01 00 38 6E 65 74 2F 72 61 6E 69 64 65 73 2F 61 73 73 69 72 61 2F 67 65 6E 65
+72 69 63 2F 53 65 72 69 61 6C 69 7A 61 62 6C 65 43 6F 64 65 54 65 73 74 24 4F 70 65 72 61 74 6F 72 01 00 08 4F 70 65 72
+61 74 6F 72 01 00 03 28 29 56 01 00 2F 6E 65 74 2F 72 61 6E 69 64 65 73 2F 61 73 73 69 72 61 2F 67 65 6E 65 72 69 63 2F
+53 65 72 69 61 6C 69 7A 61 62 6C 65 43 6F 64 65 54 65 73 74 01 00 06 61 70 70 65 6E 64 01 00 2D 28 4C 6A 61 76 61 2F 6C
+61 6E 67 2F 53 74 72 69 6E 67 3B 29 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 42 75 69 6C 64 65 72 3B 01 00 1C
+28 49 29 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 42 75 69 6C 64 65 72 3B 00 21 00 03 00 0D 00 01 00 0E 00 01
+00 12 00 0F 00 10 00 00 00 07 00 01 00 11 00 12 00 01 00 13 00 00 00 3B 00 02 00 02 00 00 00 07 1B 2A B4 00 01 6C AC 00
+00 00 02 00 14 00 00 00 06 00 01 00 00 00 4A 00 15 00 00 00 16 00 02 00 00 00 07 00 16 00 19 00 00 00 00 00 07 00 1A 00
+10 00 01 00 01 00 1B 00 1C 00 01 00 13 00 00 00 3E 00 02 00 02 00 00 00 0A 2A B7 00 02 2A 1B B5 00 01 B1 00 00 00 02 00
+14 00 00 00 06 00 01 00 00 00 43 00 15 00 00 00 16 00 02 00 00 00 0A 00 16 00 19 00 00 00 00 00 0A 00 0F 00 10 00 01 00
+01 00 1D 00 1E 00 01 00 13 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 01 AC 00 00 00 02 00 14 00 00 00 06 00 01 00 00
+00 46 00 15 00 00 00 0C 00 01 00 00 00 05 00 16 00 19 00 00 00 01 00 1F 00 20 00 01 00 13 00 00 00 7D 00 02 00 03 00 00
+00 2E 2B 2A A6 00 05 04 AC 2B C1 00 03 9A 00 05 03 AC 2B C0 00 03 4D 2C 2A B6 00 04 9A 00 05 03 AC 2A B6 00 05 2C B6 00
+05 9F 00 05 03 AC 04 AC 00 00 00 03 00 14 00 00 00 06 00 01 00 00 00 43 00 15 00 00 00 20 00 03 00 00 00 2E 00 16 00 19
+00 00 00 00 00 2E 00 21 00 22 00 01 00 15 00 19 00 23 00 19 00 02 00 24 00 00 00 0B 00 04 07 08 FC 00 0E 07 00 25 0C 00
+04 00 26 00 20 00 01 00 13 00 00 00 39 00 01 00 02 00 00 00 05 2B C1 00 03 AC 00 00 00 02 00 14 00 00 00 06 00 01 00 00
+00 43 00 15 00 00 00 16 00 02 00 00 00 05 00 16 00 19 00 00 00 00 00 05 00 23 00 22 00 01 00 01 00 27 00 1E 00 01 00 13
+00 00 00 4F 00 02 00 03 00 00 00 11 10 3B 3C 04 3D 1C 10 3B 68 2A B6 00 05 60 3D 1C AC 00 00 00 02 00 14 00 00 00 06 00
+01 00 00 00 43 00 15 00 00 00 20 00 03 00 00 00 11 00 16 00 19 00 00 00 03 00 0E 00 28 00 10 00 01 00 05 00 0C 00 29 00
+10 00 02 00 01 00 2A 00 2B 00 01 00 13 00 00 00 46 00 02 00 01 00 00 00 1C BB 00 06 59 B7 00 07 12 08 B6 00 09 2A B6 00
+05 B6 00 0A 12 0B B6 00 09 B6 00 0C B0 00 00 00 02 00 14 00 00 00 06 00 01 00 00 00 43 00 15 00 00 00 0C 00 01 00 00 00
+1C 00 16 00 19 00 00 00 02 00 2C 00 00 00 02 00 2D 00 18 00 00 00 12 00 02 00 03 00 30 00 17 00 09 00 0E 00 30 00 3C 06
+09 77 9F AC ED 00 05 73 72 00 38 6E 65 74 2E 72 61 6E 69 64 65 73 2E 61 73 73 69 72 61 2E 67 65 6E 65 72 69 63 2E 53 65
+72 69 61 6C 69 7A 61 62 6C 65 43 6F 64 65 54 65 73 74 24 44 69 76 69 64 65 72 31 92 46 A7 42 9B D3 1D A5 02 00 01 49 00
+01 61 78 72 00 2B 6E 65 74 2E 72 61 6E 69 64 65 73 2E 61 73 73 69 72 61 2E 67 65 6E 65 72 69 63 2E 53 65 72 69 61 6C 69
+7A 61 62 6C 65 43 6F 64 65 00 00 00 00 00 00 00 08 02 00 01 5A 00 0C 77 72 69 74 65 52 65 70 6C 61 63 65 78 70 00 00 00
+00 03 78

+ 61 - 0
assira/src/test/resources/bytecode/mul.txt

@@ -0,0 +1,61 @@
+//
+//    @Data
+//    public static class Multiplier1 implements Operator, Serializable {
+//
+//        private final int a;
+//
+//        @Override
+//        public int apply(int x) {
+//            return x * a;
+//        }
+//
+//    }
+//
+AC ED 00 05 73 72 00 3A 6E 65 74 2E 72 61 6E 69 64 65 73 2E 61 73 73 69 72 61 2E 67 65 6E 65 72 69 63 2E 53 65 72 69 61
+6C 69 7A 61 62 6C 65 43 6F 64 65 24 52 65 73 6F 6C 76 65 57 72 61 70 70 65 72 00 00 00 00 00 00 00 08 02 00 01 4C 00 06
+65 78 74 65 72 6E 74 00 3B 4C 6E 65 74 2F 72 61 6E 69 64 65 73 2F 61 73 73 69 72 61 2F 67 65 6E 65 72 69 63 2F 53 65 72
+69 61 6C 69 7A 61 62 6C 65 43 6F 64 65 24 43 6F 64 65 43 6F 6E 74 61 69 6E 65 72 3B 78 70 73 72 00 39 6E 65 74 2E 72 61
+6E 69 64 65 73 2E 61 73 73 69 72 61 2E 67 65 6E 65 72 69 63 2E 53 65 72 69 61 6C 69 7A 61 62 6C 65 43 6F 64 65 24 43 6F
+64 65 43 6F 6E 74 61 69 6E 65 72 00 00 00 00 00 00 00 08 03 00 01 5B 00 08 62 79 74 65 63 6F 64 65 74 00 02 5B 42 78 70
+75 72 00 02 5B 42 AC F3 17 F8 06 08 54 E0 02 00 00 78 70 00 00 06 0F CA FE BA BE 00 00 00 34 00 44 09 00 03 00 2F 0A 00
+0D 00 30 07 00 32 0A 00 03 00 33 0A 00 03 00 34 07 00 35 0A 00 06 00 30 08 00 36 0A 00 06 00 37 0A 00 06 00 38 08 00 39
+0A 00 06 00 3A 07 00 3B 07 00 3C 07 00 3E 01 00 01 61 01 00 01 49 01 00 05 61 70 70 6C 79 01 00 04 28 49 29 49 01 00 04
+43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61 6C 56 61 72 69 61 62 6C 65 54 61
+62 6C 65 01 00 04 74 68 69 73 01 00 0B 4D 75 6C 74 69 70 6C 69 65 72 31 01 00 0C 49 6E 6E 65 72 43 6C 61 73 73 65 73 01
+00 3D 4C 6E 65 74 2F 72 61 6E 69 64 65 73 2F 61 73 73 69 72 61 2F 67 65 6E 65 72 69 63 2F 53 65 72 69 61 6C 69 7A 61 62
+6C 65 43 6F 64 65 54 65 73 74 24 4D 75 6C 74 69 70 6C 69 65 72 31 3B 01 00 01 78 01 00 06 3C 69 6E 69 74 3E 01 00 04 28
+49 29 56 01 00 04 67 65 74 41 01 00 03 28 29 49 01 00 06 65 71 75 61 6C 73 01 00 15 28 4C 6A 61 76 61 2F 6C 61 6E 67 2F
+4F 62 6A 65 63 74 3B 29 5A 01 00 01 6F 01 00 12 4C 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 3B 01 00 05 6F 74 68
+65 72 01 00 0D 53 74 61 63 6B 4D 61 70 54 61 62 6C 65 07 00 32 01 00 08 63 61 6E 45 71 75 61 6C 01 00 08 68 61 73 68 43
+6F 64 65 01 00 05 50 52 49 4D 45 01 00 06 72 65 73 75 6C 74 01 00 08 74 6F 53 74 72 69 6E 67 01 00 14 28 29 4C 6A 61 76
+61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F 75 72 63 65 46 69 6C 65 01 00 19 53 65 72 69 61 6C 69 7A 61 62
+6C 65 43 6F 64 65 54 65 73 74 2E 6A 61 76 61 0C 00 10 00 11 0C 00 1C 00 3F 07 00 40 01 00 3B 6E 65 74 2F 72 61 6E 69 64
+65 73 2F 61 73 73 69 72 61 2F 67 65 6E 65 72 69 63 2F 53 65 72 69 61 6C 69 7A 61 62 6C 65 43 6F 64 65 54 65 73 74 24 4D
+75 6C 74 69 70 6C 69 65 72 31 0C 00 27 00 21 0C 00 1E 00 1F 01 00 17 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 42
+75 69 6C 64 65 72 01 00 23 53 65 72 69 61 6C 69 7A 61 62 6C 65 43 6F 64 65 54 65 73 74 2E 4D 75 6C 74 69 70 6C 69 65 72
+31 28 61 3D 0C 00 41 00 42 0C 00 41 00 43 01 00 01 29 0C 00 2B 00 2C 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65
+63 74 01 00 38 6E 65 74 2F 72 61 6E 69 64 65 73 2F 61 73 73 69 72 61 2F 67 65 6E 65 72 69 63 2F 53 65 72 69 61 6C 69 7A
+61 62 6C 65 43 6F 64 65 54 65 73 74 24 4F 70 65 72 61 74 6F 72 01 00 08 4F 70 65 72 61 74 6F 72 01 00 14 6A 61 76 61 2F
+69 6F 2F 53 65 72 69 61 6C 69 7A 61 62 6C 65 01 00 03 28 29 56 01 00 2F 6E 65 74 2F 72 61 6E 69 64 65 73 2F 61 73 73 69
+72 61 2F 67 65 6E 65 72 69 63 2F 53 65 72 69 61 6C 69 7A 61 62 6C 65 43 6F 64 65 54 65 73 74 01 00 06 61 70 70 65 6E 64
+01 00 2D 28 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67
+42 75 69 6C 64 65 72 3B 01 00 1C 28 49 29 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 42 75 69 6C 64 65 72 3B 00
+21 00 03 00 0D 00 02 00 0E 00 0F 00 01 00 12 00 10 00 11 00 00 00 07 00 01 00 12 00 13 00 01 00 14 00 00 00 3B 00 02 00
+02 00 00 00 07 1B 2A B4 00 01 68 AC 00 00 00 02 00 15 00 00 00 06 00 01 00 00 00 62 00 16 00 00 00 16 00 02 00 00 00 07
+00 17 00 1A 00 00 00 00 00 07 00 1B 00 11 00 01 00 01 00 1C 00 1D 00 01 00 14 00 00 00 3E 00 02 00 02 00 00 00 0A 2A B7
+00 02 2A 1B B5 00 01 B1 00 00 00 02 00 15 00 00 00 06 00 01 00 00 00 5B 00 16 00 00 00 16 00 02 00 00 00 0A 00 17 00 1A
+00 00 00 00 00 0A 00 10 00 11 00 01 00 01 00 1E 00 1F 00 01 00 14 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 01 AC 00
+00 00 02 00 15 00 00 00 06 00 01 00 00 00 5E 00 16 00 00 00 0C 00 01 00 00 00 05 00 17 00 1A 00 00 00 01 00 20 00 21 00
+01 00 14 00 00 00 7D 00 02 00 03 00 00 00 2E 2B 2A A6 00 05 04 AC 2B C1 00 03 9A 00 05 03 AC 2B C0 00 03 4D 2C 2A B6 00
+04 9A 00 05 03 AC 2A B6 00 05 2C B6 00 05 9F 00 05 03 AC 04 AC 00 00 00 03 00 15 00 00 00 06 00 01 00 00 00 5B 00 16 00
+00 00 20 00 03 00 00 00 2E 00 17 00 1A 00 00 00 00 00 2E 00 22 00 23 00 01 00 15 00 19 00 24 00 1A 00 02 00 25 00 00 00
+0B 00 04 07 08 FC 00 0E 07 00 26 0C 00 04 00 27 00 21 00 01 00 14 00 00 00 39 00 01 00 02 00 00 00 05 2B C1 00 03 AC 00
+00 00 02 00 15 00 00 00 06 00 01 00 00 00 5B 00 16 00 00 00 16 00 02 00 00 00 05 00 17 00 1A 00 00 00 00 00 05 00 24 00
+23 00 01 00 01 00 28 00 1F 00 01 00 14 00 00 00 4F 00 02 00 03 00 00 00 11 10 3B 3C 04 3D 1C 10 3B 68 2A B6 00 05 60 3D
+1C AC 00 00 00 02 00 15 00 00 00 06 00 01 00 00 00 5B 00 16 00 00 00 20 00 03 00 00 00 11 00 17 00 1A 00 00 00 03 00 0E
+00 29 00 11 00 01 00 05 00 0C 00 2A 00 11 00 02 00 01 00 2B 00 2C 00 01 00 14 00 00 00 46 00 02 00 01 00 00 00 1C BB 00
+06 59 B7 00 07 12 08 B6 00 09 2A B6 00 05 B6 00 0A 12 0B B6 00 09 B6 00 0C B0 00 00 00 02 00 15 00 00 00 06 00 01 00 00
+00 5B 00 16 00 00 00 0C 00 01 00 00 00 1C 00 17 00 1A 00 00 00 02 00 2D 00 00 00 02 00 2E 00 19 00 00 00 12 00 02 00 03
+00 31 00 18 00 09 00 0E 00 31 00 3D 06 09 77 58 AC ED 00 05 73 72 00 3B 6E 65 74 2E 72 61 6E 69 64 65 73 2E 61 73 73 69
+72 61 2E 67 65 6E 65 72 69 63 2E 53 65 72 69 61 6C 69 7A 61 62 6C 65 43 6F 64 65 54 65 73 74 24 4D 75 6C 74 69 70 6C 69
+65 72 31 3D 27 ED 4D 22 65 CF 0B 02 00 01 49 00 01 61 78 70 00 00 00 05 78

+ 1 - 1
pom.xml

@@ -219,7 +219,7 @@
             <dependency>
                 <groupId>net.ranides</groupId>
                 <artifactId>assira.asm</artifactId>
-                <version>7.1</version>
+                <version>7.2</version>
             </dependency>
             <dependency>
                 <groupId>net.ranides</groupId>