<commit_before>package uk.co.rockstable.experiements.codegen.reflection.extractors.impl;

import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import uk.co.rockstable.experiements.codegen.reflection.extractors.Extractor;
import uk.co.rockstable.experiements.codegen.reflection.extractors.ExtractorFactory;
import uk.co.rockstable.experiements.codegen.reflection.utils.UnsafeUtils;

import java.lang.reflect.Field;
import java.util.concurrent.atomic.AtomicInteger;

import static org.objectweb.asm.Opcodes.*;

public class MagicExtractorFactory extends ExtractorFactory {
    private static AtomicInteger ID = new AtomicInteger();


    public Extractor create(Class<?> clazz, String fieldName) {
        try {
            Field field = clazz.getDeclaredField(fieldName);
            return createMagicExtractorInstance(clazz, field);
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        }
    }

    private Extractor createMagicExtractorInstance(Class<?> clazz, Field field) {
        final String generatedClassName = generateClassName();
        final byte[] generatedBytecode = generateExtractorByteCode(field, generatedClassName);
        ClassLoader cl = clazz.getClassLoader();
        Class<?> generatedClass = UnsafeUtils.UNSAFE.defineClass(generatedClassName, generatedBytecode, 0, generatedBytecode.length, cl, null);
        return createNewInstance(generatedClass);
    }

    private Extractor createNewInstance(Class<?> generatedClass) {
        try {
            return (Extractor) generatedClass.newInstance();
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    private byte[] generateExtractorByteCode(Field field, String generatedClassName) {
        String declaringClassName = field.getDeclaringClass().getName().replace('.', '/');
        ClassWriter cw = new ClassWriter(0);
        MethodVisitor mv;

        String fieldName = field.getName();
        Class<?> fieldTypeClass = field.getType();
        TypeDefinition fieldTypeEnum = TypeDefinition.fromClass(fieldTypeClass);
        String fieldTypeString = fieldTypeEnum.getFieldTypeString(fieldTypeClass);

        cw.visit(52, ACC_PUBLIC + ACC_SUPER, generatedClassName,
                null, "sun/reflect/MagicAccessorImpl",
                new String[]{"uk/co/rockstable/experiements/codegen/reflection/extractors/Extractor"});

        {
            mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
            mv.visitCode();
            mv.visitVarInsn(ALOAD, 0);
            mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
            mv.visitInsn(RETURN);
            mv.visitMaxs(1, 1);
            mv.visitEnd();
        }
        {
            mv = cw.visitMethod(ACC_PUBLIC, "extract", "(Ljava/lang/Object;)Ljava/lang/Object;", null, null);
            mv.visitCode();
            mv.visitVarInsn(ALOAD, 1);
            mv.visitFieldInsn(GETFIELD, declaringClassName, fieldName, fieldTypeString);
            boxPrimitiveTypeIfNecessary(mv, fieldTypeEnum);
            mv.visitInsn(ARETURN);
            mv.visitMaxs(1, 2);
            mv.visitEnd();
        }
        cw.visitEnd();
        return cw.toByteArray();
    }

    private String generateClassName() {
        return "uk/co/rockstable/experiements/codegen/reflection/GeneratedExtractor$" + ID.incrementAndGet();
    }

    private void boxPrimitiveTypeIfNecessary(MethodVisitor mv, TypeDefinition fieldTypeEnum) {
        if (fieldTypeEnum.isPrimitive()) {
            String boxingClass = fieldTypeEnum.getBoxingClass();
            String boxingMethodSignature = fieldTypeEnum.getBoxingMethodSignature();
            mv.visitMethodInsn(INVOKESTATIC, boxingClass, "valueOf", boxingMethodSignature, false);
        }<commit_msg>tiny refactoring<commit_after>package uk.co.rockstable.experiements.codegen.reflection.extractors.impl;

import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import uk.co.rockstable.experiements.codegen.reflection.extractors.Extractor;
import uk.co.rockstable.experiements.codegen.reflection.extractors.ExtractorFactory;
import uk.co.rockstable.experiements.codegen.reflection.utils.UnsafeUtils;

import java.lang.reflect.Field;
import java.util.concurrent.atomic.AtomicInteger;

import static org.objectweb.asm.Opcodes.*;

public class MagicExtractorFactory extends ExtractorFactory {
    private static AtomicInteger ID = new AtomicInteger();


    public Extractor create(Class<?> clazz, String fieldName) {
        try {
            Field field = clazz.getDeclaredField(fieldName);
            return createMagicExtractorInstance(clazz, field);
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        }
    }

    private Extractor createMagicExtractorInstance(Class<?> clazz, Field field) {
        final String generatedClassName = generateClassName();
        final byte[] generatedBytecode = generateExtractorByteCode(field, generatedClassName);
        ClassLoader cl = clazz.getClassLoader();
        Class<?> generatedClass = UnsafeUtils.UNSAFE.defineClass(generatedClassName, generatedBytecode, 0, generatedBytecode.length, cl, null);
        return createNewInstance(generatedClass);
    }

    private Extractor createNewInstance(Class<?> generatedClass) {
        try {
            return (Extractor) generatedClass.newInstance();
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    private byte[] generateExtractorByteCode(Field field, String generatedClassName) {
        String declaringClassName = field.getDeclaringClass().getName().replace('.', '/');
        ClassWriter cw = new ClassWriter(0);
        MethodVisitor mv;

        String fieldName = field.getName();
        Class<?> fieldTypeClass = field.getType();
        TypeDefinition fieldTypeEnum = TypeDefinition.fromClass(fieldTypeClass);
        String fieldTypeString = fieldTypeEnum.getFieldTypeString(fieldTypeClass);

        cw.visit(52, ACC_PUBLIC + ACC_SUPER, generatedClassName,
                null, "sun/reflect/MagicAccessorImpl",
                new String[]{"uk/co/rockstable/experiements/codegen/reflection/extractors/Extractor"});

        writeConstructor(cw);

        {
            mv = cw.visitMethod(ACC_PUBLIC, "extract", "(Ljava/lang/Object;)Ljava/lang/Object;", null, null);
            mv.visitCode();
            mv.visitVarInsn(ALOAD, 1);
            mv.visitFieldInsn(GETFIELD, declaringClassName, fieldName, fieldTypeString);
            boxPrimitiveTypeIfNecessary(mv, fieldTypeEnum);
            mv.visitInsn(ARETURN);
            mv.visitMaxs(1, 2);
            mv.visitEnd();
        }
        cw.visitEnd();
        return cw.toByteArray();
    }

    private void writeConstructor(ClassWriter cw) {
        MethodVisitor mv;
        mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
        mv.visitInsn(RETURN);
        mv.visitMaxs(1, 1);
        mv.visitEnd();
    }

    private String generateClassName() {
        return "uk/co/rockstable/experiements/codegen/reflection/GeneratedExtractor$" + ID.incrementAndGet();
    }

    private void boxPrimitiveTypeIfNecessary(MethodVisitor mv, TypeDefinition fieldTypeEnum) {
        if (fieldTypeEnum.isPrimitive()) {
            String boxingClass = fieldTypeEnum.getBoxingClass();
            String boxingMethodSignature = fieldTypeEnum.getBoxingMethodSignature();
            mv.visitMethodInsn(INVOKESTATIC, boxingClass, "valueOf", boxingMethodSignature, false);
        }
{'fraction_non_alphanumeric': 0.10497168030207678, 'fraction_numerical': 0.0025173064820641915, 'mean_word_length': 3.1580324437467295, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6726203', 'n_tokens_mistral': 2261, 'n_tokens_neox': 2175, 'n_words': 402}