导航菜单

页面标题

页面副标题

Kaspi.kz v5.85.1 - ASMAccessorOptimizer.java 源代码

正在查看: Kaspi.kz v5.85.1 应用的 ASMAccessorOptimizer.java JAVA 源代码文件

本页面展示 JAVA 反编译生成的源代码文件,支持语法高亮显示。 仅供安全研究与技术分析使用,严禁用于任何非法用途。请遵守相关法律法规。


package org.mvel2.optimizers.impl.asm;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintStream;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import o.bIW;
import org.mvel2.CompileException;
import org.mvel2.DataConversion;
import org.mvel2.MVEL;
import org.mvel2.OptimizationFailure;
import org.mvel2.ParserContext;
import org.mvel2.PropertyAccessException;
import org.mvel2.asm.ClassWriter;
import org.mvel2.asm.Label;
import org.mvel2.asm.MethodVisitor;
import org.mvel2.asm.Opcodes;
import org.mvel2.asm.Type;
import org.mvel2.ast.TypeDescriptor;
import org.mvel2.ast.WithNode;
import org.mvel2.compiler.AbstractParser;
import org.mvel2.compiler.Accessor;
import org.mvel2.compiler.ExecutableLiteral;
import org.mvel2.compiler.ExecutableStatement;
import org.mvel2.compiler.PropertyVerifier;
import org.mvel2.integration.GlobalListenerFactory;
import org.mvel2.integration.PropertyHandler;
import org.mvel2.integration.PropertyHandlerFactory;
import org.mvel2.integration.VariableResolverFactory;
import org.mvel2.optimizers.AbstractOptimizer;
import org.mvel2.optimizers.AccessorOptimizer;
import org.mvel2.optimizers.OptimizationNotSupported;
import org.mvel2.optimizers.impl.refl.nodes.Union;
import org.mvel2.util.ArrayTools;
import org.mvel2.util.JITClassLoader;
import org.mvel2.util.MVELClassLoader;
import org.mvel2.util.ParseTools;
import org.mvel2.util.PropertyTools;
import org.mvel2.util.ReflectionUtil;
import org.mvel2.util.StringAppender;

public class ASMAccessorOptimizer extends AbstractOptimizer implements AccessorOptimizer {
    static final boolean $assertionsDisabled = false;
    private static final int ARRAY = 0;
    private static final Object[] EMPTYARG;
    private static final Class[] EMPTYCLS;
    private static final int LIST = 1;
    private static String LIST_IMPL = null;
    private static final int MAP = 2;
    private static final String MAP_IMPL = "java/util/HashMap";
    private static String NAMESPACE = null;
    private static final int OPCODES_VERSION;
    private static final int VAL = 3;
    private static MVELClassLoader classLoader;
    private StringAppender buildLog;
    private String className;
    private int compileDepth;
    private ArrayList<ExecutableStatement> compiledInputs;
    private Object ctx;
    private ClassWriter cw;
    private boolean deferFinish;
    private boolean first;
    private Class ingressType;
    private boolean literal;
    private int maxlocals;
    private boolean methNull;
    private MethodVisitor mv;
    private boolean noinit;
    private boolean propNull;
    private Class returnType;
    private int stacksize;
    private Object thisRef;
    private long time;
    private Object val;
    private VariableResolverFactory variableFactory;

    static {
        String javaVersion = PropertyTools.getJavaVersion();
        if (javaVersion.startsWith("1.4")) {
            OPCODES_VERSION = 48;
        } else if (javaVersion.startsWith("1.5")) {
            OPCODES_VERSION = 49;
        } else {
            OPCODES_VERSION = 50;
        }
        String property = System.getProperty("mvel2.namespace");
        if (property == null) {
            NAMESPACE = "org/mvel2/";
        } else {
            NAMESPACE = property;
        }
        String property2 = System.getProperty("mvel2.jit.list_impl");
        if (property2 == null) {
            LIST_IMPL = NAMESPACE + "util/FastList";
        } else {
            LIST_IMPL = property2;
        }
        EMPTYARG = new Object[0];
        EMPTYCLS = new Class[0];
    }

    public ASMAccessorOptimizer() {
        this.first = true;
        this.noinit = $assertionsDisabled;
        this.deferFinish = $assertionsDisabled;
        this.literal = $assertionsDisabled;
        this.propNull = $assertionsDisabled;
        this.methNull = $assertionsDisabled;
        this.stacksize = 1;
        this.maxlocals = 1;
        this.compileDepth = 0;
        new ClassWriter(1);
    }

    private ASMAccessorOptimizer(ClassWriter classWriter, MethodVisitor methodVisitor, ArrayList<ExecutableStatement> arrayList, String str, StringAppender stringAppender, int i) {
        this.first = true;
        this.literal = $assertionsDisabled;
        this.propNull = $assertionsDisabled;
        this.methNull = $assertionsDisabled;
        this.stacksize = 1;
        this.maxlocals = 1;
        this.cw = classWriter;
        this.mv = methodVisitor;
        this.compiledInputs = arrayList;
        this.className = str;
        this.buildLog = stringAppender;
        this.compileDepth = i + 1;
        this.noinit = true;
        this.deferFinish = true;
    }

    private void _initJIT() {
        if (MVEL.isAdvancedDebugging()) {
            this.buildLog = new StringAppender();
        }
        this.cw = new ClassWriter(3);
        synchronized (Runtime.getRuntime()) {
            ClassWriter classWriter = this.cw;
            int i = OPCODES_VERSION;
            String str = "ASMAccessorImpl_" + String.valueOf(this.cw.hashCode()).replaceAll("\\-", "_") + (System.currentTimeMillis() / 10) + ((int) (Math.random() * 100.0d));
            this.className = str;
            classWriter.visit(i, 33, str, null, "java/lang/Object", new String[]{NAMESPACE + "compiler/Accessor"});
        }
        MethodVisitor visitMethod = this.cw.visitMethod(1, "<init>", "()V", null, null);
        visitMethod.visitCode();
        visitMethod.visitVarInsn(25, 0);
        visitMethod.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
        visitMethod.visitInsn(Opcodes.RETURN);
        visitMethod.visitMaxs(1, 1);
        visitMethod.visitEnd();
        MethodVisitor visitMethod2 = this.cw.visitMethod(1, "getValue", "(Ljava/lang/Object;Ljava/lang/Object;L" + NAMESPACE + "integration/VariableResolverFactory;)Ljava/lang/Object;", null, null);
        this.mv = visitMethod2;
        visitMethod2.visitCode();
    }

    private void _initJIT2() {
        if (MVEL.isAdvancedDebugging()) {
            this.buildLog = new StringAppender();
        }
        this.cw = new ClassWriter(3);
        synchronized (Runtime.getRuntime()) {
            ClassWriter classWriter = this.cw;
            int i = OPCODES_VERSION;
            String str = "ASMAccessorImpl_" + String.valueOf(this.cw.hashCode()).replaceAll("\\-", "_") + (System.currentTimeMillis() / 10) + ((int) (Math.random() * 100.0d));
            this.className = str;
            classWriter.visit(i, 33, str, null, "java/lang/Object", new String[]{NAMESPACE + "compiler/Accessor"});
        }
        MethodVisitor visitMethod = this.cw.visitMethod(1, "<init>", "()V", null, null);
        visitMethod.visitCode();
        visitMethod.visitVarInsn(25, 0);
        visitMethod.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
        visitMethod.visitInsn(Opcodes.RETURN);
        visitMethod.visitMaxs(1, 1);
        visitMethod.visitEnd();
        MethodVisitor visitMethod2 = this.cw.visitMethod(1, "setValue", "(Ljava/lang/Object;Ljava/lang/Object;L" + NAMESPACE + "integration/VariableResolverFactory;Ljava/lang/Object;)Ljava/lang/Object;", null, null);
        this.mv = visitMethod2;
        visitMethod2.visitCode();
    }

    @Override
    public Accessor optimizeAccessor(ParserContext parserContext, char[] cArr, int i, int i2, Object obj, Object obj2, VariableResolverFactory variableResolverFactory, boolean z, Class cls) {
        this.time = System.currentTimeMillis();
        if (this.compiledInputs == null) {
            this.compiledInputs = new ArrayList<>();
        }
        this.cursor = i;
        this.start = i;
        int i3 = i2 + i;
        this.end = i3;
        this.length = i3 - i;
        this.first = true;
        this.val = null;
        this.pCtx = parserContext;
        this.expr = cArr;
        this.ctx = obj;
        this.thisRef = obj2;
        this.variableFactory = variableResolverFactory;
        this.ingressType = cls;
        if (!this.noinit) {
            _initJIT();
        }
        return compileAccessor();
    }

    @Override
    public Accessor optimizeSetAccessor(ParserContext parserContext, char[] cArr, int i, int i2, Object obj, Object obj2, VariableResolverFactory variableResolverFactory, boolean z, Object obj3, Class cls) {
        InvocationTargetException invocationTargetException;
        IllegalAccessException illegalAccessException;
        Label label;
        ?? r2 = parserContext;
        Object obj4 = obj3;
        this.expr = cArr;
        this.cursor = i;
        this.start = i;
        int i3 = i + i2;
        this.end = i3;
        this.length = i3;
        this.first = true;
        this.ingressType = cls;
        this.compiledInputs = new ArrayList<>();
        Object obj5 = obj;
        this.ctx = obj5;
        this.thisRef = obj2;
        this.variableFactory = variableResolverFactory;
        this.pCtx = r2;
        PropertyVerifier propertyVerifier = new PropertyVerifier(cArr, (ParserContext) r2);
        int findLastUnion = findLastUnion();
        char[] subset = findLastUnion != -1 ? ParseTools.subset(cArr, 0, findLastUnion) : null;
        _initJIT2();
        if (subset != null) {
            int i4 = this.length;
            char[] cArr2 = this.expr;
            this.expr = subset;
            int length = subset.length;
            this.end = length;
            this.length = length;
            this.deferFinish = true;
            this.noinit = true;
            compileAccessor();
            Object obj6 = this.val;
            this.expr = cArr2;
            int length2 = subset.length + i + 1;
            this.cursor = length2;
            int length3 = (i4 - subset.length) - 1;
            this.length = length3;
            this.end = length2 + length3;
            obj5 = obj6;
        } else {
            this.mv.visitVarInsn(25, 1);
        }
        try {
            skipWhitespace();
            if (this.collection) {
                try {
                    int i5 = this.cursor;
                    whiteSpaceSkip();
                    if (i5 == this.end) {
                        throw new PropertyAccessException("unterminated '['", this.expr, i, r2);
                    }
                    if (scanTo(']')) {
                        throw new PropertyAccessException("unterminated '['", this.expr, i, r2);
                    }
                    String trim = new String(this.expr, i5, this.cursor - i5).trim();
                    this.mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(obj5.getClass()));
                    if (obj5 instanceof Map) {
                        if (MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING && PropertyHandlerFactory.hasPropertyHandler(Map.class)) {
                            propHandlerByteCodePut(trim, obj5, Map.class, obj4);
                        } else {
                            Map map = (Map) obj5;
                            Object eval = MVEL.eval(trim, obj5, this.variableFactory);
                            Class analyze = propertyVerifier.analyze();
                            this.returnType = analyze;
                            map.put(eval, DataConversion.convert(obj4, analyze));
                            writeLiteralOrSubexpression(ParseTools.subCompileExpression(trim.toCharArray(), (ParserContext) r2));
                            this.mv.visitVarInsn(25, 4);
                            if (obj4 != null && this.returnType != obj3.getClass()) {
                                dataConversion(this.returnType);
                                checkcast(this.returnType);
                            }
                            this.mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
                            this.mv.visitInsn(87);
                            this.mv.visitVarInsn(25, 4);
                        }
                    } else if (obj5 instanceof List) {
                        if (MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING && PropertyHandlerFactory.hasPropertyHandler(List.class)) {
                            propHandlerByteCodePut(trim, obj5, List.class, obj4);
                        } else {
                            List list = (List) obj5;
                            int intValue = ((Integer) MVEL.eval(trim, obj5, this.variableFactory, Integer.class)).intValue();
                            Class analyze2 = propertyVerifier.analyze();
                            this.returnType = analyze2;
                            list.set(intValue, DataConversion.convert(obj4, analyze2));
                            writeLiteralOrSubexpression(ParseTools.subCompileExpression(trim.toCharArray(), (ParserContext) r2));
                            unwrapPrimitive(Integer.TYPE);
                            this.mv.visitVarInsn(25, 4);
                            if (obj4 != null && !obj3.getClass().isAssignableFrom(this.returnType)) {
                                dataConversion(this.returnType);
                                checkcast(this.returnType);
                            }
                            this.mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List", "set", "(ILjava/lang/Object;)Ljava/lang/Object;");
                            this.mv.visitVarInsn(25, 4);
                        }
                    } else if (MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING && PropertyHandlerFactory.hasPropertyHandler(obj5.getClass())) {
                        propHandlerByteCodePut(trim, obj5, obj5.getClass(), obj4);
                    } else if (obj5.getClass().isArray()) {
                        if (MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING && PropertyHandlerFactory.hasPropertyHandler(Array.class)) {
                            propHandlerByteCodePut(trim, obj5, Array.class, obj4);
                        } else {
                            Class baseComponentType = ParseTools.getBaseComponentType(obj5.getClass());
                            Object eval2 = MVEL.eval(trim, obj5, this.variableFactory);
                            Serializable subCompileExpression = ParseTools.subCompileExpression(trim.toCharArray(), (ParserContext) r2);
                            Class cls2 = Integer.TYPE;
                            writeLiteralOrSubexpression(subCompileExpression, cls2);
                            if (!(eval2 instanceof Integer)) {
                                dataConversion(Integer.class);
                                eval2 = DataConversion.convert(eval2, Integer.class);
                                unwrapPrimitive(cls2);
                            }
                            this.mv.visitVarInsn(25, 4);
                            if (baseComponentType.isPrimitive()) {
                                unwrapPrimitive(baseComponentType);
                            } else if (!baseComponentType.equals(obj3.getClass())) {
                                dataConversion(baseComponentType);
                            }
                            arrayStore(baseComponentType);
                            Array.set(obj5, ((Integer) eval2).intValue(), DataConversion.convert(obj4, baseComponentType));
                            this.mv.visitVarInsn(25, 4);
                        }
                    } else {
                        throw new PropertyAccessException("cannot bind to collection property: " + new String(this.expr) + ": not a recognized collection type: " + obj5.getClass(), this.expr, i, r2);
                    }
                    this.deferFinish = $assertionsDisabled;
                    this.noinit = $assertionsDisabled;
                    _finishJIT();
                    try {
                        this.deferFinish = $assertionsDisabled;
                        r2 = _initializeAccessor();
                        return r2;
                    } catch (Exception e) {
                        throw new CompileException("could not generate accessor", this.expr, i, e);
                    }
                } catch (IllegalAccessException e2) {
                    illegalAccessException = e2;
                    throw new PropertyAccessException("could not access property", this.expr, i, illegalAccessException, parserContext);
                } catch (InvocationTargetException e3) {
                    invocationTargetException = e3;
                    throw new PropertyAccessException("could not access property", this.expr, i, invocationTargetException, parserContext);
                }
            }
            char[] cArr3 = this.expr;
            int i6 = this.cursor;
            String str = new String(cArr3, i6, this.end - i6);
            Member fieldOrWriteAccessor = PropertyTools.getFieldOrWriteAccessor(obj5.getClass(), str, obj4 == null ? null : cls);
            if (GlobalListenerFactory.hasSetListeners()) {
                try {
                    this.mv.visitVarInsn(25, 1);
                    this.mv.visitLdcInsn(str);
                    this.mv.visitVarInsn(25, 3);
                    this.mv.visitVarInsn(25, 4);
                    this.mv.visitMethodInsn(Opcodes.INVOKESTATIC, NAMESPACE + "integration/GlobalListenerFactory", "notifySetListeners", "(Ljava/lang/Object;Ljava/lang/String;L" + NAMESPACE + "integration/VariableResolverFactory;Ljava/lang/Object;)V");
                    GlobalListenerFactory.notifySetListeners(obj5, str, this.variableFactory, obj4);
                } catch (IllegalAccessException e4) {
                    e = e4;
                    illegalAccessException = e;
                    throw new PropertyAccessException("could not access property", this.expr, i, illegalAccessException, parserContext);
                } catch (InvocationTargetException e5) {
                    e = e5;
                    invocationTargetException = e;
                    throw new PropertyAccessException("could not access property", this.expr, i, invocationTargetException, parserContext);
                }
            }
            if (fieldOrWriteAccessor instanceof Field) {
                checkcast(obj5.getClass());
                Field field = (Field) fieldOrWriteAccessor;
                Label label2 = new Label();
                if (field.getType().isPrimitive()) {
                    this.mv.visitVarInsn(58, 5);
                    this.mv.visitVarInsn(25, 4);
                    if (obj4 == null) {
                        obj4 = PropertyTools.getPrimitiveInitialValue(field.getType());
                    }
                    label = new Label();
                    this.mv.visitJumpInsn(Opcodes.IFNONNULL, label);
                    this.mv.visitVarInsn(25, 5);
                    this.mv.visitInsn(3);
                    this.mv.visitFieldInsn(Opcodes.PUTFIELD, Type.getInternalName(field.getDeclaringClass()), str, Type.getDescriptor(field.getType()));
                    this.mv.visitJumpInsn(Opcodes.GOTO, label2);
                    this.mv.visitLabel(label);
                    this.mv.visitVarInsn(25, 5);
                    this.mv.visitVarInsn(25, 4);
                    unwrapPrimitive(field.getType());
                } else {
                    this.mv.visitVarInsn(25, 4);
                    checkcast(field.getType());
                    label = null;
                }
                if (label == null && obj4 != null && !field.getType().isAssignableFrom(obj4.getClass())) {
                    if (!DataConversion.canConvert(field.getType(), obj4.getClass())) {
                        throw new CompileException("cannot convert type: " + obj4.getClass() + ": to " + field.getType(), this.expr, i);
                    }
                    dataConversion(field.getType());
                    field.set(obj5, DataConversion.convert(obj4, field.getType()));
                } else {
                    field.set(obj5, obj4);
                }
                this.mv.visitFieldInsn(Opcodes.PUTFIELD, Type.getInternalName(field.getDeclaringClass()), str, Type.getDescriptor(field.getType()));
                this.mv.visitLabel(label2);
                this.mv.visitVarInsn(25, 4);
            } else if (fieldOrWriteAccessor != null) {
                this.mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(obj5.getClass()));
                Method method = (Method) fieldOrWriteAccessor;
                this.mv.visitVarInsn(25, 4);
                Class<?> cls3 = method.getParameterTypes()[0];
                Label label3 = new Label();
                if (obj4 != null && !cls3.isAssignableFrom(obj3.getClass())) {
                    if (!DataConversion.canConvert(cls3, obj3.getClass())) {
                        throw new CompileException("cannot convert type: " + obj3.getClass() + ": to " + method.getParameterTypes()[0], this.expr, i);
                    }
                    dataConversion(getWrapperClass(cls3));
                    if (cls3.isPrimitive()) {
                        unwrapPrimitive(cls3);
                    } else {
                        checkcast(cls3);
                    }
                    method.invoke(obj5, DataConversion.convert(obj4, method.getParameterTypes()[0]));
                } else {
                    if (cls3.isPrimitive()) {
                        if (obj4 == null) {
                            obj4 = PropertyTools.getPrimitiveInitialValue(cls3);
                        }
                        Label label4 = new Label();
                        this.mv.visitJumpInsn(Opcodes.IFNONNULL, label4);
                        this.mv.visitInsn(3);
                        this.mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(method.getDeclaringClass()), method.getName(), Type.getMethodDescriptor(method));
                        this.mv.visitJumpInsn(Opcodes.GOTO, label3);
                        this.mv.visitLabel(label4);
                        this.mv.visitVarInsn(25, 4);
                        unwrapPrimitive(cls3);
                    } else {
                        checkcast(cls3);
                    }
                    method.invoke(obj5, obj4);
                }
                this.mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(method.getDeclaringClass()), method.getName(), Type.getMethodDescriptor(method));
                this.mv.visitLabel(label3);
                this.mv.visitVarInsn(25, 4);
            } else if (obj5 instanceof Map) {
                this.mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(obj5.getClass()));
                this.mv.visitLdcInsn(str);
                this.mv.visitVarInsn(25, 4);
                this.mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
                this.mv.visitVarInsn(25, 4);
                ((Map) obj5).put(str, obj4);
            } else {
                try {
                    throw new PropertyAccessException("could not access property (" + str + ") in: " + cls.getName(), this.expr, i, parserContext);
                } catch (IllegalAccessException e6) {
                    e = e6;
                    illegalAccessException = e;
                    throw new PropertyAccessException("could not access property", this.expr, i, illegalAccessException, parserContext);
                } catch (InvocationTargetException e7) {
                    e = e7;
                    invocationTargetException = e;
                    throw new PropertyAccessException("could not access property", this.expr, i, invocationTargetException, parserContext);
                }
            }
            try {
                this.deferFinish = $assertionsDisabled;
                this.noinit = $assertionsDisabled;
                _finishJIT();
                return _initializeAccessor();
            } catch (Exception e8) {
                throw new CompileException("could not generate accessor", this.expr, i, e8);
            }
        } catch (IllegalAccessException e9) {
            e = e9;
            illegalAccessException = e;
            throw new PropertyAccessException("could not access property", this.expr, i, illegalAccessException, parserContext);
        } catch (InvocationTargetException e10) {
            e = e10;
            invocationTargetException = e;
            throw new PropertyAccessException("could not access property", this.expr, i, invocationTargetException, parserContext);
        }
    }

    private void _finishJIT() {
        if (this.deferFinish) {
            return;
        }
        Class cls = this.returnType;
        if (cls != null && cls.isPrimitive()) {
            wrapPrimitive(this.returnType);
        }
        if (this.returnType == Void.TYPE) {
            this.mv.visitInsn(1);
        }
        this.mv.visitInsn(Opcodes.ARETURN);
        dumpAdvancedDebugging();
        this.mv.visitMaxs(this.stacksize, this.maxlocals);
        this.mv.visitEnd();
        MethodVisitor visitMethod = this.cw.visitMethod(1, "getKnownEgressType", "()Ljava/lang/Class;", null, null);
        this.mv = visitMethod;
        visitMethod.visitCode();
        visitConstantClass(this.returnType);
        this.mv.visitInsn(Opcodes.ARETURN);
        this.mv.visitMaxs(1, 1);
        this.mv.visitEnd();
        if (this.propNull) {
            this.cw.visitField(1, "nullPropertyHandler", "L" + NAMESPACE + "integration/PropertyHandler;", null, null).visitEnd();
        }
        if (this.methNull) {
            this.cw.visitField(1, "nullMethodHandler", "L" + NAMESPACE + "integration/PropertyHandler;", null, null).visitEnd();
        }
        buildInputs();
        StringAppender stringAppender = this.buildLog;
        if (stringAppender != null && stringAppender.length() != 0 && this.expr != null) {
            MethodVisitor visitMethod2 = this.cw.visitMethod(1, "toString", "()Ljava/lang/String;", null, null);
            this.mv = visitMethod2;
            visitMethod2.visitCode();
            this.mv.visitLabel(new Label());
            this.mv.visitLdcInsn(this.buildLog.toString() + "\n\n## { " + new String(this.expr) + " }");
            this.mv.visitInsn(Opcodes.ARETURN);
            this.mv.visitLabel(new Label());
            this.mv.visitMaxs(1, 1);
            this.mv.visitEnd();
        }
        this.cw.visitEnd();
    }

    private void visitConstantClass(Class<?> cls) {
        if (cls == null) {
            cls = Object.class;
        }
        if (cls.isPrimitive()) {
            this.mv.visitFieldInsn(Opcodes.GETSTATIC, ReflectionUtil.toNonPrimitiveType(cls).getName().replace(".", "/"), "TYPE", "Ljava/lang/Class;");
        } else {
            this.mv.visitLdcInsn(Type.getType(cls));
        }
    }

    private Accessor _initializeAccessor() throws Exception {
        Object newInstance;
        if (this.deferFinish) {
            return null;
        }
        Class loadClass = loadClass(this.className, this.cw.toByteArray());
        try {
            if (this.compiledInputs.size() == 0) {
                newInstance = loadClass.newInstance();
            } else {
                Class<?>[] clsArr = new Class[this.compiledInputs.size()];
                for (int i = 0; i < this.compiledInputs.size(); i++) {
                    clsArr[i] = ExecutableStatement.class;
                }
                Constructor constructor = loadClass.getConstructor(clsArr);
                ArrayList<ExecutableStatement> arrayList = this.compiledInputs;
                newInstance = constructor.newInstance(arrayList.toArray(new ExecutableStatement[arrayList.size()]));
            }
            if (this.propNull) {
                loadClass.getField("nullPropertyHandler").set(newInstance, PropertyHandlerFactory.getNullPropertyHandler());
            }
            if (this.methNull) {
                loadClass.getField("nullMethodHandler").set(newInstance, PropertyHandlerFactory.getNullMethodHandler());
            }
            return (Accessor) newInstance;
        } catch (VerifyError e) {
            PrintStream printStream = System.out;
            printStream.println("**** COMPILER BUG! REPORT THIS IMMEDIATELY AT http://jira.codehaus.org/browse/MVEL");
            StringBuilder sb = new StringBuilder();
            sb.append("Expression: ");
            char[] cArr = this.expr;
            sb.append(cArr != null ? new String(cArr) : null);
            printStream.println(sb.toString());
            throw e;
        }
    }

    private Accessor compileAccessor() {
        Object obj = this.ctx;
        try {
            if (MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING) {
                while (true) {
                    if (this.cursor >= this.end) {
                        break;
                    }
                    int nextSubToken = nextSubToken();
                    if (nextSubToken == 0) {
                        obj = getBeanPropertyAO(obj, capture());
                    } else if (nextSubToken == 1) {
                        obj = getMethod(obj, capture());
                    } else if (nextSubToken == 2) {
                        obj = getCollectionPropertyAO(obj, capture());
                    } else if (nextSubToken == 3) {
                        obj = getWithProperty(obj);
                    }
                    if (this.fields == -1) {
                        if (obj == null) {
                            if (this.nullSafe) {
                                throw new OptimizationNotSupported();
                            }
                        } else {
                            this.fields = 0;
                        }
                    }
                    this.first = $assertionsDisabled;
                    if (this.nullSafe && this.cursor < this.end) {
                        this.mv.visitInsn(89);
                        Label label = new Label();
                        this.mv.visitJumpInsn(Opcodes.IFNONNULL, label);
                        this.mv.visitInsn(Opcodes.ARETURN);
                        this.mv.visitLabel(label);
                    }
                }
            } else {
                while (true) {
                    if (this.cursor >= this.end) {
                        break;
                    }
                    int nextSubToken2 = nextSubToken();
                    if (nextSubToken2 == 0) {
                        obj = getBeanProperty(obj, capture());
                    } else if (nextSubToken2 == 1) {
                        obj = getMethod(obj, capture());
                    } else if (nextSubToken2 == 2) {
                        obj = getCollectionProperty(obj, capture());
                    } else if (nextSubToken2 == 3) {
                        obj = getWithProperty(obj);
                    }
                    if (this.fields == -1) {
                        if (obj == null) {
                            if (this.nullSafe) {
                                throw new OptimizationNotSupported();
                            }
                        } else {
                            this.fields = 0;
                        }
                    }
                    this.first = $assertionsDisabled;
                    if (this.nullSafe && this.cursor < this.end) {
                        this.mv.visitInsn(89);
                        Label label2 = new Label();
                        this.mv.visitJumpInsn(Opcodes.IFNONNULL, label2);
                        this.mv.visitInsn(Opcodes.ARETURN);
                        this.mv.visitLabel(label2);
                    }
                }
            }
            this.val = obj;
            _finishJIT();
            return _initializeAccessor();
        } catch (IllegalAccessException e) {
            throw new PropertyAccessException(new String(this.expr), this.expr, this.st, e, this.pCtx);
        } catch (IndexOutOfBoundsException e2) {
            throw new PropertyAccessException(new String(this.expr), this.expr, this.st, e2, this.pCtx);
        } catch (NullPointerException e3) {
            throw new PropertyAccessException(new String(this.expr), this.expr, this.st, e3, this.pCtx);
        } catch (InvocationTargetException e4) {
            throw new PropertyAccessException(new String(this.expr), this.expr, this.st, e4, this.pCtx);
        } catch (PropertyAccessException e5) {
            throw new CompileException(e5.getMessage(), this.expr, this.st, e5);
        } catch (CompileException e6) {
            throw e6;
        } catch (OptimizationNotSupported e7) {
            throw e7;
        } catch (Exception e8) {
            throw new CompileException(e8.getMessage(), this.expr, this.st, e8);
        }
    }

    private Object getWithProperty(Object obj) {
        if (this.first) {
            this.mv.visitVarInsn(25, 1);
            this.first = $assertionsDisabled;
        }
        String trim = new String(this.expr, 0, this.cursor - 1).trim();
        int i = this.cursor;
        int i2 = i + 1;
        this.cursor = ParseTools.balancedCaptureWithLineAccounting(this.expr, i, this.end, '{', this.pCtx);
        this.returnType = obj != null ? obj.getClass() : null;
        char[] cArr = this.expr;
        int i3 = this.cursor;
        this.cursor = i3 + 1;
        for (WithNode.ParmValuePair parmValuePair : WithNode.compileWithExpressions(cArr, i2, i3 - i2, trim, this.ingressType, this.pCtx)) {
            this.mv.visitInsn(89);
            this.mv.visitVarInsn(58, this.compileDepth + 5);
            parmValuePair.eval(obj, this.variableFactory);
            if (parmValuePair.getSetExpression() == null) {
                addSubstatement(parmValuePair.getStatement());
            } else {
                this.compiledInputs.add((ExecutableStatement) parmValuePair.getSetExpression());
                this.mv.visitVarInsn(25, 0);
                this.mv.visitFieldInsn(Opcodes.GETFIELD, this.className, "p" + (this.compiledInputs.size() - 1), "L" + NAMESPACE + "compiler/ExecutableStatement;");
                this.mv.visitVarInsn(25, this.compileDepth + 5);
                this.mv.visitVarInsn(25, 2);
                this.mv.visitVarInsn(25, 3);
                addSubstatement(parmValuePair.getStatement());
                this.mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, NAMESPACE + "compiler/ExecutableStatement", "setValue", "(Ljava/lang/Object;Ljava/lang/Object;L" + NAMESPACE + "integration/VariableResolverFactory;Ljava/lang/Object;)Ljava/lang/Object;");
                this.mv.visitInsn(87);
            }
        }
        return obj;
    }

    private Object getBeanPropertyAO(Object obj, String str) throws IllegalAccessException, InvocationTargetException {
        if (obj != null && PropertyHandlerFactory.hasPropertyHandler(obj.getClass())) {
            return propHandlerByteCode(str, obj, obj.getClass());
        }
        return getBeanProperty(obj, str);
    }

    private Object getBeanProperty(Object obj, String str) throws IllegalAccessException, InvocationTargetException {
        boolean z;
        Class<?> cls;
        Object invoke;
        ParserContext parserContext = this.pCtx;
        if ((parserContext == null ? this.currType : parserContext.getVarOrInputTypeOrNull(str)) == Object.class && !this.pCtx.isStrongTyping()) {
            this.currType = null;
        }
        Class cls2 = this.returnType;
        if (cls2 != null && cls2.isPrimitive()) {
            wrapPrimitive(this.returnType);
        }
        boolean z2 = obj instanceof Class;
        if (z2) {
            if (MVEL.COMPILER_OPT_SUPPORT_JAVA_STYLE_CLASS_LITERALS && "class".equals(str)) {
                ldcClassConstant((Class) obj);
                return obj;
            }
            cls = (Class) obj;
            z = true;
        } else if (obj != null) {
            cls = obj.getClass();
            z = false;
        } else {
            z = false;
            cls = null;
        }
        if (PropertyHandlerFactory.hasPropertyHandler(cls)) {
            PropertyHandler propertyHandler = PropertyHandlerFactory.getPropertyHandler(cls);
            if (propertyHandler instanceof ProducesBytecode) {
                ((ProducesBytecode) propertyHandler).produceBytecodeGet(this.mv, str, this.variableFactory);
                return propertyHandler.getProperty(str, obj, this.variableFactory);
            }
            throw new RuntimeException("unable to compileShared: custom accessor does not support producing bytecode: " + propertyHandler.getClass().getName());
        }
        Member fieldOrAccessor = cls != null ? PropertyTools.getFieldOrAccessor(cls, str) : null;
        if (fieldOrAccessor != null && z && (fieldOrAccessor.getModifiers() & 8) == 0) {
            fieldOrAccessor = null;
        }
        if (fieldOrAccessor != null && GlobalListenerFactory.hasGetListeners()) {
            this.mv.visitVarInsn(25, 1);
            this.mv.visitLdcInsn(fieldOrAccessor.getName());
            this.mv.visitVarInsn(25, 3);
            this.mv.visitMethodInsn(Opcodes.INVOKESTATIC, NAMESPACE + "integration/GlobalListenerFactory", "notifyGetListeners", "(Ljava/lang/Object;Ljava/lang/String;L" + NAMESPACE + "integration/VariableResolverFactory;)V");
            GlobalListenerFactory.notifyGetListeners(obj, fieldOrAccessor.getName(), this.variableFactory);
        }
        if (this.first) {
            if ("this".equals(str)) {
                this.mv.visitVarInsn(25, 2);
                return this.thisRef;
            }
            VariableResolverFactory variableResolverFactory = this.variableFactory;
            if (variableResolverFactory != null && variableResolverFactory.isResolveable(str)) {
                if (this.variableFactory.isIndexedFactory() && this.variableFactory.isTarget(str)) {
                    try {
                        int variableIndexOf = this.variableFactory.variableIndexOf(str);
                        loadVariableByIndex(variableIndexOf);
                        return this.variableFactory.getIndexedVariableResolver(variableIndexOf).getValue();
                    } catch (Exception unused) {
                        throw new OptimizationFailure(str);
                    }
                }
                try {
                    loadVariableByName(str);
                    return this.variableFactory.getVariableResolver(str).getValue();
                } catch (Exception e) {
                    throw new OptimizationFailure("critical error in JIT", e);
                }
            }
            this.mv.visitVarInsn(25, 1);
        }
        if (fieldOrAccessor instanceof Field) {
            return optimizeFieldMethodProperty(obj, str, cls, fieldOrAccessor);
        }
        if (fieldOrAccessor != null) {
            if (this.first) {
                this.mv.visitVarInsn(25, 1);
            }
            try {
                invoke = ((Method) fieldOrAccessor).invoke(obj, EMPTYARG);
                if (this.returnType != fieldOrAccessor.getDeclaringClass()) {
                    this.mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(fieldOrAccessor.getDeclaringClass()));
                }
                this.returnType = ((Method) fieldOrAccessor).getReturnType();
                if (fieldOrAccessor.getDeclaringClass().isInterface()) {
                    this.mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getInternalName(fieldOrAccessor.getDeclaringClass()), fieldOrAccessor.getName(), Type.getMethodDescriptor((Method) fieldOrAccessor));
                } else {
                    this.mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(fieldOrAccessor.getDeclaringClass()), fieldOrAccessor.getName(), Type.getMethodDescriptor((Method) fieldOrAccessor));
                }
            } catch (IllegalAccessException e2) {
                Method method = (Method) fieldOrAccessor;
                Method determineActualTargetMethod = ParseTools.determineActualTargetMethod(method);
                if (determineActualTargetMethod == null) {
                    throw new PropertyAccessException("could not access field: " + cls.getName() + "." + str, this.expr, this.st, e2, this.pCtx);
                }
                this.mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(determineActualTargetMethod.getDeclaringClass()));
                this.returnType = determineActualTargetMethod.getReturnType();
                this.mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getInternalName(determineActualTargetMethod.getDeclaringClass()), fieldOrAccessor.getName(), Type.getMethodDescriptor(method));
                invoke = determineActualTargetMethod.invoke(obj, EMPTYARG);
            } catch (IllegalArgumentException e3) {
                if (fieldOrAccessor.getDeclaringClass().equals(obj)) {
                    try {
                        throw new CompileException("name collision between innerclass: " + Class.forName(fieldOrAccessor.getDeclaringClass().getName() + "$" + str).getCanonicalName() + "; and bean accessor: " + str + " (" + fieldOrAccessor.toString() + ")", this.expr, this.tkStart);
                    } catch (ClassNotFoundException unused2) {
                        throw e3;
                    }
                }
                throw e3;
            }
            if (PropertyHandlerFactory.hasNullPropertyHandler()) {
                if (invoke == null) {
                    invoke = PropertyHandlerFactory.getNullPropertyHandler().getProperty(fieldOrAccessor.getName(), obj, this.variableFactory);
                }
                writeOutNullHandler(fieldOrAccessor, 0);
            }
            this.currType = ReflectionUtil.toNonPrimitiveType(this.returnType);
            return invoke;
        }
        if (obj instanceof Map) {
            Map map = (Map) obj;
            if (map.containsKey(str) || this.nullSafe) {
                this.mv.visitTypeInsn(Opcodes.CHECKCAST, "java/util/Map");
                this.mv.visitLdcInsn(str);
                this.mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map", "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
                return map.get(str);
            }
        }
        if (this.first && "this".equals(str)) {
            this.mv.visitVarInsn(25, 2);
            return this.thisRef;
        }
        if ("length".equals(str) && obj.getClass().isArray()) {
            anyArrayCheck(obj.getClass());
            this.mv.visitInsn(Opcodes.ARRAYLENGTH);
            wrapPrimitive(Integer.TYPE);
            return Integer.valueOf(Array.getLength(obj));
        }
        if (AbstractParser.LITERALS.containsKey(str)) {
            Object obj2 = AbstractParser.LITERALS.get(str);
            if (obj2 instanceof Class) {
                ldcClassConstant((Class) obj2);
            }
            return obj2;
        }
        Object tryStaticAccess = tryStaticAccess();
        if (tryStaticAccess != null) {
            if (tryStaticAccess instanceof Class) {
                ldcClassConstant((Class) tryStaticAccess);
                return tryStaticAccess;
            }
            if (tryStaticAccess instanceof Method) {
                Method method2 = (Method) tryStaticAccess;
                writeFunctionPointerStub(method2.getDeclaringClass(), method2);
                return tryStaticAccess;
            }
            return optimizeFieldMethodProperty(obj, str, cls, (Field) tryStaticAccess);
        }
        if (z2) {
            Class cls3 = (Class) obj;
            for (Method method3 : cls3.getMethods()) {
                if (str.equals(method3.getName())) {
                    ParserContext parserContext2 = this.pCtx;
                    if (parserContext2 == null || parserContext2.getParserConfiguration() == null ? MVEL.COMPILER_OPT_ALLOW_NAKED_METH_CALL : this.pCtx.getParserConfiguration().isAllowNakedMethCall()) {
                        this.mv.visitInsn(87);
                        this.mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(method3.getDeclaringClass()), method3.getName(), Type.getMethodDescriptor(method3));
                        this.returnType = method3.getReturnType();
                        return method3.invoke(null, ParseTools.EMPTY_OBJ_ARR);
                    }
                    writeFunctionPointerStub(cls3, method3);
                    return method3;
                }
            }
            try {
                Class findClass = ParseTools.findClass(this.variableFactory, cls3.getName() + "$" + str, this.pCtx);
                ldcClassConstant(findClass);
                return findClass;
            } catch (ClassNotFoundException unused3) {
            }
        } else {
            ParserContext parserContext3 = this.pCtx;
            if (parserContext3 == null || parserContext3.getParserConfiguration() == null ? MVEL.COMPILER_OPT_ALLOW_NAKED_METH_CALL : this.pCtx.getParserConfiguration().isAllowNakedMethCall()) {
                return getMethod(obj, str);
            }
        }
        if (obj == null) {
            throw new PropertyAccessException("unresolvable property or identifier: " + str, this.expr, this.st, this.pCtx);
        }
        throw new PropertyAccessException("could not access: " + str + "; in class: " + obj.getClass().getName(), this.expr, this.st, this.pCtx);
    }

    private Object optimizeFieldMethodProperty(Object obj, String str, Class<?> cls, Member member) throws IllegalAccessException {
        Field field = (Field) member;
        Object obj2 = field.get(obj);
        if ((member.getModifiers() & 8) != 0) {
            if ((member.getModifiers() & 16) != 0 && ((obj2 instanceof String) || field.getType().isPrimitive())) {
                Object obj3 = field.get(null);
                this.mv.visitLdcInsn(obj3);
                wrapPrimitive(obj3.getClass());
                if (PropertyHandlerFactory.hasNullPropertyHandler()) {
                    writeOutNullHandler(member, 0);
                }
                return obj3;
            }
            MethodVisitor methodVisitor = this.mv;
            String internalName = Type.getInternalName(member.getDeclaringClass());
            String name = member.getName();
            Class<?> type = field.getType();
            this.returnType = type;
            methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, internalName, name, Type.getDescriptor(type));
        } else {
            this.mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(cls));
            MethodVisitor methodVisitor2 = this.mv;
            String internalName2 = Type.getInternalName(cls);
            Class<?> type2 = field.getType();
            this.returnType = type2;
            methodVisitor2.visitFieldInsn(Opcodes.GETFIELD, internalName2, str, Type.getDescriptor(type2));
        }
        this.returnType = field.getType();
        if (PropertyHandlerFactory.hasNullPropertyHandler()) {
            if (obj2 == null) {
                obj2 = PropertyHandlerFactory.getNullPropertyHandler().getProperty(member.getName(), obj, this.variableFactory);
            }
            writeOutNullHandler(member, 0);
        }
        this.currType = ReflectionUtil.toNonPrimitiveType(this.returnType);
        return obj2;
    }

    private void writeFunctionPointerStub(Class cls, Method method) {
        ldcClassConstant(cls);
        this.mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Class", "getMethods", "()[Ljava/lang/reflect/Method;");
        this.mv.visitVarInsn(58, 7);
        this.mv.visitInsn(3);
        this.mv.visitVarInsn(54, 5);
        this.mv.visitVarInsn(25, 7);
        this.mv.visitInsn(Opcodes.ARRAYLENGTH);
        this.mv.visitVarInsn(54, 6);
        Label label = new Label();
        this.mv.visitJumpInsn(Opcodes.GOTO, label);
        Label label2 = new Label();
        this.mv.visitLabel(label2);
        this.mv.visitVarInsn(25, 7);
        this.mv.visitVarInsn(21, 5);
        this.mv.visitInsn(50);
        this.mv.visitVarInsn(58, 4);
        this.mv.visitLabel(new Label());
        this.mv.visitLdcInsn(method.getName());
        this.mv.visitVarInsn(25, 4);
        this.mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Method", "getName", "()Ljava/lang/String;");
        this.mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z");
        Label label3 = new Label();
        this.mv.visitJumpInsn(Opcodes.IFEQ, label3);
        this.mv.visitLabel(new Label());
        this.mv.visitVarInsn(25, 4);
        this.mv.visitInsn(Opcodes.ARETURN);
        this.mv.visitLabel(label3);
        this.mv.visitIincInsn(5, 1);
        this.mv.visitLabel(label);
        this.mv.visitVarInsn(21, 5);
        this.mv.visitVarInsn(21, 6);
        this.mv.visitJumpInsn(Opcodes.IF_ICMPLT, label2);
        this.mv.visitLabel(new Label());
        this.mv.visitInsn(1);
        this.mv.visitInsn(Opcodes.ARETURN);
    }

    private Object getCollectionProperty(Object obj, String str) throws IllegalAccessException, InvocationTargetException {
        if (str.trim().length() > 0) {
            obj = getBeanProperty(obj, str);
            this.first = $assertionsDisabled;
        }
        this.currType = null;
        int i = this.cursor + 1;
        this.cursor = i;
        skipWhitespace();
        if (this.cursor == this.end) {
            throw new CompileException("unterminated '['", this.expr, this.st);
        }
        if (scanTo(']')) {
            throw new CompileException("unterminated '['", this.expr, this.st);
        }
        String str2 = new String(this.expr, i, this.cursor - i);
        if (obj == null) {
            return null;
        }
        if (this.first) {
            this.mv.visitVarInsn(25, 1);
        }
        ExecutableStatement executableStatement = (ExecutableStatement) ParseTools.subCompileExpression(str2.toCharArray(), this.pCtx);
        Object value = executableStatement.getValue(this.ctx, this.variableFactory);
        this.cursor++;
        if (obj instanceof Map) {
            this.mv.visitTypeInsn(Opcodes.CHECKCAST, "java/util/Map");
            Class writeLiteralOrSubexpression = writeLiteralOrSubexpression(executableStatement);
            if (writeLiteralOrSubexpression != null && writeLiteralOrSubexpression.isPrimitive()) {
                wrapPrimitive(writeLiteralOrSubexpression);
            }
            this.mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map", "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
            return ((Map) obj).get(value);
        }
        if (obj instanceof List) {
            this.mv.visitTypeInsn(Opcodes.CHECKCAST, "java/util/List");
            writeLiteralOrSubexpression(executableStatement, Integer.TYPE);
            this.mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List", "get", "(I)Ljava/lang/Object;");
            return ((List) obj).get(((Integer) DataConversion.convert(value, Integer.class)).intValue());
        }
        if (obj.getClass().isArray()) {
            this.mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getDescriptor(obj.getClass()));
            Class cls = Integer.TYPE;
            writeLiteralOrSubexpression(executableStatement, cls, value.getClass());
            Class baseComponentType = ParseTools.getBaseComponentType(obj.getClass());
            if (baseComponentType.isPrimitive()) {
                if (baseComponentType == cls) {
                    this.mv.visitInsn(46);
                } else if (baseComponentType == Character.TYPE) {
                    this.mv.visitInsn(52);
                } else if (baseComponentType == Boolean.TYPE) {
                    this.mv.visitInsn(51);
                } else if (baseComponentType == Double.TYPE) {
                    this.mv.visitInsn(49);
                } else if (baseComponentType == Float.TYPE) {
                    this.mv.visitInsn(48);
                } else if (baseComponentType == Short.TYPE) {
                    this.mv.visitInsn(53);
                } else if (baseComponentType == Long.TYPE) {
                    this.mv.visitInsn(47);
                } else if (baseComponentType == Byte.TYPE) {
                    this.mv.visitInsn(51);
                }
                wrapPrimitive(baseComponentType);
            } else {
                this.mv.visitInsn(50);
            }
            return Array.get(obj, ((Integer) DataConversion.convert(value, Integer.class)).intValue());
        }
        if (obj instanceof CharSequence) {
            this.mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/CharSequence");
            if (value instanceof Integer) {
                Integer num = (Integer) value;
                intPush(num.intValue());
                this.mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/lang/CharSequence", "charAt", "(I)C");
                wrapPrimitive(Character.TYPE);
                return Character.valueOf(((CharSequence) obj).charAt(num.intValue()));
            }
            writeLiteralOrSubexpression(executableStatement, Integer.class);
            unwrapPrimitive(Integer.TYPE);
            this.mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/lang/CharSequence", "charAt", "(I)C");
            wrapPrimitive(Character.TYPE);
            return Character.valueOf(((CharSequence) obj).charAt(((Integer) DataConversion.convert(value, Integer.class)).intValue()));
        }
        TypeDescriptor typeDescriptor = new TypeDescriptor(this.expr, this.start, this.length, 0);
        if (typeDescriptor.isArray()) {
            try {
                Class classReference = TypeDescriptor.getClassReference((Class) obj, typeDescriptor, this.variableFactory, this.pCtx);
                ldcClassConstant(classReference);
                return classReference;
            } catch (Exception unused) {
            }
        }
        throw new CompileException("illegal use of []: unknown type: " + obj.getClass().getName(), this.expr, this.st);
    }

    private Object getCollectionPropertyAO(Object obj, String str) throws IllegalAccessException, InvocationTargetException {
        if (str.length() > 0) {
            obj = getBeanProperty(obj, str);
            this.first = $assertionsDisabled;
        }
        this.currType = null;
        int i = this.cursor + 1;
        this.cursor = i;
        skipWhitespace();
        if (this.cursor == this.end) {
            throw new CompileException("unterminated '['", this.expr, this.st);
        }
        if (scanTo(']')) {
            throw new CompileException("unterminated '['", this.expr, this.st);
        }
        String str2 = new String(this.expr, i, this.cursor - i);
        if (obj == null) {
            return null;
        }
        ExecutableStatement executableStatement = (ExecutableStatement) ParseTools.subCompileExpression(str2.toCharArray());
        Object value = executableStatement.getValue(this.ctx, this.variableFactory);
        this.cursor++;
        if (obj instanceof Map) {
            if (PropertyHandlerFactory.hasPropertyHandler(Map.class)) {
                return propHandlerByteCode(str2, obj, Map.class);
            }
            if (this.first) {
                this.mv.visitVarInsn(25, 1);
            }
            this.mv.visitTypeInsn(Opcodes.CHECKCAST, "java/util/Map");
            Class writeLiteralOrSubexpression = writeLiteralOrSubexpression(executableStatement);
            if (writeLiteralOrSubexpression != null && writeLiteralOrSubexpression.isPrimitive()) {
                wrapPrimitive(writeLiteralOrSubexpression);
            }
            this.mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map", "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
            return ((Map) obj).get(value);
        }
        if (obj instanceof List) {
            if (PropertyHandlerFactory.hasPropertyHandler(List.class)) {
                return propHandlerByteCode(str2, obj, List.class);
            }
            if (this.first) {
                this.mv.visitVarInsn(25, 1);
            }
            this.mv.visitTypeInsn(Opcodes.CHECKCAST, "java/util/List");
            writeLiteralOrSubexpression(executableStatement, Integer.TYPE);
            this.mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List", "get", "(I)Ljava/lang/Object;");
            return ((List) obj).get(((Integer) DataConversion.convert(value, Integer.class)).intValue());
        }
        if (obj.getClass().isArray()) {
            if (PropertyHandlerFactory.hasPropertyHandler(Array.class)) {
                return propHandlerByteCode(str2, obj, Array.class);
            }
            if (this.first) {
                this.mv.visitVarInsn(25, 1);
            }
            this.mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getDescriptor(obj.getClass()));
            Class cls = Integer.TYPE;
            writeLiteralOrSubexpression(executableStatement, cls, value.getClass());
            Class baseComponentType = ParseTools.getBaseComponentType(obj.getClass());
            if (baseComponentType.isPrimitive()) {
                if (baseComponentType == cls) {
                    this.mv.visitInsn(46);
                } else if (baseComponentType == Character.TYPE) {
                    this.mv.visitInsn(52);
                } else if (baseComponentType == Boolean.TYPE) {
                    this.mv.visitInsn(51);
                } else if (baseComponentType == Double.TYPE) {
                    this.mv.visitInsn(49);
                } else if (baseComponentType == Float.TYPE) {
                    this.mv.visitInsn(48);
                } else if (baseComponentType == Short.TYPE) {
                    this.mv.visitInsn(53);
                } else if (baseComponentType == Long.TYPE) {
                    this.mv.visitInsn(47);
                } else if (baseComponentType == Byte.TYPE) {
                    this.mv.visitInsn(51);
                }
                wrapPrimitive(baseComponentType);
            } else {
                this.mv.visitInsn(50);
            }
            return Array.get(obj, ((Integer) DataConversion.convert(value, Integer.class)).intValue());
        }
        if (obj instanceof CharSequence) {
            if (PropertyHandlerFactory.hasPropertyHandler(CharSequence.class)) {
                return propHandlerByteCode(str2, obj, CharSequence.class);
            }
            if (this.first) {
                this.mv.visitVarInsn(25, 1);
            }
            this.mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/CharSequence");
            if (value instanceof Integer) {
                Integer num = (Integer) value;
                intPush(num.intValue());
                this.mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/lang/CharSequence", "charAt", "(I)C");
                wrapPrimitive(Character.TYPE);
                return Character.valueOf(((CharSequence) obj).charAt(num.intValue()));
            }
            writeLiteralOrSubexpression(executableStatement, Integer.class);
            unwrapPrimitive(Integer.TYPE);
            this.mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/lang/CharSequence", "charAt", "(I)C");
            wrapPrimitive(Character.TYPE);
            return Character.valueOf(((CharSequence) obj).charAt(((Integer) DataConversion.convert(value, Integer.class)).intValue()));
        }
        char[] cArr = this.expr;
        int i2 = this.start;
        TypeDescriptor typeDescriptor = new TypeDescriptor(cArr, i2, this.end - i2, 0);
        if (typeDescriptor.isArray()) {
            try {
                Class classReference = TypeDescriptor.getClassReference((Class) obj, typeDescriptor, this.variableFactory, this.pCtx);
                ldcClassConstant(classReference);
                return classReference;
            } catch (Exception unused) {
            }
        }
        throw new CompileException("illegal use of []: unknown type: " + obj.getClass().getName(), this.expr, this.st);
    }

    private java.lang.Object getMethod(java.lang.Object r27, java.lang.String r28) throws java.lang.IllegalAccessException, java.lang.reflect.InvocationTargetException {
        throw new UnsupportedOperationException("Method not decompiled: org.mvel2.optimizers.impl.asm.ASMAccessorOptimizer.getMethod(java.lang.Object, java.lang.String):java.lang.Object");
    }

    private void dataConversion(Class cls) {
        if (cls.equals(Object.class)) {
            return;
        }
        ldcClassConstant(cls);
        this.mv.visitMethodInsn(Opcodes.INVOKESTATIC, NAMESPACE + "DataConversion", "convert", "(Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;");
    }

    public static void setMVELClassLoader(MVELClassLoader mVELClassLoader) {
        classLoader = mVELClassLoader;
    }

    public static MVELClassLoader getMVELClassLoader() {
        return classLoader;
    }

    @Override
    public void init() {
        try {
            classLoader = new JITClassLoader(Thread.currentThread().getContextClassLoader());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private ContextClassLoader getContextClassLoader() {
        if (this.pCtx == null) {
            return null;
        }
        return new ContextClassLoader(this.pCtx.getClassLoader());
    }

    static class ContextClassLoader extends ClassLoader {
        ContextClassLoader(ClassLoader classLoader) {
            super(classLoader);
        }

        Class<?> defineClass(String str, byte[] bArr) {
            return defineClass(str, bArr, 0, bArr.length);
        }
    }

    private Class loadClass(String str, byte[] bArr) throws Exception {
        ContextClassLoader contextClassLoader = getContextClassLoader();
        if (contextClassLoader == null) {
            return classLoader.defineClassX(str, bArr, 0, bArr.length);
        }
        return contextClassLoader.defineClass(str, bArr);
    }

    private boolean debug(String str) {
        StringAppender stringAppender = this.buildLog;
        if (stringAppender == null) {
            return true;
        }
        stringAppender.append(str).append("\n");
        return true;
    }

    public String getName() {
        return "ASM";
    }

    @Override
    public Object getResultOptPass() {
        return this.val;
    }

    private Class getWrapperClass(Class cls) {
        if (cls == Boolean.TYPE) {
            return Boolean.class;
        }
        if (cls == Integer.TYPE) {
            return Integer.class;
        }
        if (cls == Float.TYPE) {
            return Float.class;
        }
        if (cls == Double.TYPE) {
            return Double.class;
        }
        if (cls == Short.TYPE) {
            return Short.class;
        }
        if (cls == Long.TYPE) {
            return Long.class;
        }
        if (cls == Byte.TYPE) {
            return Byte.class;
        }
        return cls == Character.TYPE ? Character.class : cls;
    }

    private void unwrapPrimitive(Class cls) {
        if (cls == Boolean.TYPE) {
            this.mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Boolean");
            this.mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z");
            return;
        }
        if (cls == Integer.TYPE) {
            this.mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Integer");
            this.mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I");
            return;
        }
        if (cls == Float.TYPE) {
            this.mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Float");
            this.mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F");
            return;
        }
        if (cls == Double.TYPE) {
            this.mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Double");
            this.mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D");
            return;
        }
        if (cls == Short.TYPE) {
            this.mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Short");
            this.mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S");
            return;
        }
        if (cls == Long.TYPE) {
            this.mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Long");
            this.mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J");
        } else if (cls == Byte.TYPE) {
            this.mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Byte");
            this.mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B");
        } else if (cls == Character.TYPE) {
            this.mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Character");
            this.mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C");
        }
    }

    private void wrapPrimitive(Class<? extends Object> cls) {
        if (OPCODES_VERSION == 48) {
            debug("** Using 1.4 Bytecode **");
            if (cls == Boolean.TYPE || cls == Boolean.class) {
                debug("NEW java/lang/Boolean");
                this.mv.visitTypeInsn(Opcodes.NEW, "java/lang/Boolean");
                debug("DUP X1");
                this.mv.visitInsn(90);
                debug("SWAP");
                this.mv.visitInsn(95);
                debug("INVOKESPECIAL java/lang/Boolean.<init>::(Z)V");
                this.mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Boolean", "<init>", "(Z)V");
                return;
            }
            if (cls == Integer.TYPE || cls == Integer.class) {
                debug("NEW java/lang/Integer");
                this.mv.visitTypeInsn(Opcodes.NEW, "java/lang/Integer");
                debug("DUP X1");
                this.mv.visitInsn(90);
                debug("SWAP");
                this.mv.visitInsn(95);
                debug("INVOKESPECIAL java/lang/Integer.<init>::(I)V");
                this.mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Integer", "<init>", "(I)V");
                return;
            }
            if (cls == Float.TYPE || cls == Float.class) {
                debug("NEW java/lang/Float");
                this.mv.visitTypeInsn(Opcodes.NEW, "java/lang/Float");
                debug("DUP X1");
                this.mv.visitInsn(90);
                debug("SWAP");
                this.mv.visitInsn(95);
                debug("INVOKESPECIAL java/lang/Float.<init>::(F)V");
                this.mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Float", "<init>", "(F)V");
                return;
            }
            if (cls == Double.TYPE || cls == Double.class) {
                debug("NEW java/lang/Double");
                this.mv.visitTypeInsn(Opcodes.NEW, "java/lang/Double");
                debug("DUP X2");
                this.mv.visitInsn(91);
                debug("DUP X2");
                this.mv.visitInsn(91);
                debug("POP");
                this.mv.visitInsn(87);
                debug("INVOKESPECIAL java/lang/Double.<init>::(D)V");
                this.mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Double", "<init>", "(D)V");
                return;
            }
            if (cls == Short.TYPE || cls == Short.class) {
                debug("NEW java/lang/Short");
                this.mv.visitTypeInsn(Opcodes.NEW, "java/lang/Short");
                debug("DUP X1");
                this.mv.visitInsn(90);
                debug("SWAP");
                this.mv.visitInsn(95);
                debug("INVOKESPECIAL java/lang/Short.<init>::(S)V");
                this.mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Short", "<init>", "(S)V");
                return;
            }
            if (cls == Long.TYPE || cls == Long.class) {
                debug("NEW java/lang/Long");
                this.mv.visitTypeInsn(Opcodes.NEW, "java/lang/Long");
                debug("DUP X1");
                this.mv.visitInsn(90);
                debug("SWAP");
                this.mv.visitInsn(95);
                debug("INVOKESPECIAL java/lang/Long.<init>::(L)V");
                this.mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Float", "<init>", "(L)V");
                return;
            }
            if (cls == Byte.TYPE || cls == Byte.class) {
                debug("NEW java/lang/Byte");
                this.mv.visitTypeInsn(Opcodes.NEW, "java/lang/Byte");
                debug("DUP X1");
                this.mv.visitInsn(90);
                debug("SWAP");
                this.mv.visitInsn(95);
                debug("INVOKESPECIAL java/lang/Byte.<init>::(B)V");
                this.mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Byte", "<init>", "(B)V");
                return;
            }
            if (cls == Character.TYPE || cls == Character.class) {
                debug("NEW java/lang/Character");
                this.mv.visitTypeInsn(Opcodes.NEW, "java/lang/Character");
                debug("DUP X1");
                this.mv.visitInsn(90);
                debug("SWAP");
                this.mv.visitInsn(95);
                debug("INVOKESPECIAL java/lang/Character.<init>::(C)V");
                this.mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Character", "<init>", "(C)V");
                return;
            }
            return;
        }
        if (cls == Boolean.TYPE || cls == Boolean.class) {
            debug("INVOKESTATIC java/lang/Boolean.valueOf");
            this.mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;");
            return;
        }
        if (cls == Integer.TYPE || cls == Integer.class) {
            debug("INVOKESTATIC java/lang/Integer.valueOf");
            this.mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;");
            return;
        }
        if (cls == Float.TYPE || cls == Float.class) {
            debug("INVOKESTATIC java/lang/Float.valueOf");
            this.mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;");
            return;
        }
        if (cls == Double.TYPE || cls == Double.class) {
            debug("INVOKESTATIC java/lang/Double.valueOf");
            this.mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;");
            return;
        }
        if (cls == Short.TYPE || cls == Short.class) {
            debug("INVOKESTATIC java/lang/Short.valueOf");
            this.mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;");
            return;
        }
        if (cls == Long.TYPE || cls == Long.class) {
            debug("INVOKESTATIC java/lang/Long.valueOf");
            this.mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;");
        } else if (cls == Byte.TYPE || cls == Byte.class) {
            debug("INVOKESTATIC java/lang/Byte.valueOf");
            this.mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;");
        } else if (cls == Character.TYPE || cls == Character.class) {
            debug("INVOKESTATIC java/lang/Character.valueOf");
            this.mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;");
        }
    }

    private void anyArrayCheck(Class cls) {
        if (cls == boolean[].class) {
            this.mv.visitTypeInsn(Opcodes.CHECKCAST, "[Z");
            return;
        }
        if (cls == int[].class) {
            this.mv.visitTypeInsn(Opcodes.CHECKCAST, "[I");
            return;
        }
        if (cls == float[].class) {
            this.mv.visitTypeInsn(Opcodes.CHECKCAST, "[F");
            return;
        }
        if (cls == double[].class) {
            this.mv.visitTypeInsn(Opcodes.CHECKCAST, "[D");
            return;
        }
        if (cls == short[].class) {
            this.mv.visitTypeInsn(Opcodes.CHECKCAST, "[S");
            return;
        }
        if (cls == long[].class) {
            this.mv.visitTypeInsn(Opcodes.CHECKCAST, "[J");
            return;
        }
        if (cls == byte[].class) {
            this.mv.visitTypeInsn(Opcodes.CHECKCAST, "[B");
        } else if (cls == char[].class) {
            this.mv.visitTypeInsn(Opcodes.CHECKCAST, "[C");
        } else {
            this.mv.visitTypeInsn(Opcodes.CHECKCAST, "[Ljava/lang/Object;");
        }
    }

    private void writeOutLiteralWrapped(Object obj) {
        if (obj instanceof Integer) {
            intPush(((Integer) obj).intValue());
            wrapPrimitive(Integer.TYPE);
            return;
        }
        if (obj instanceof String) {
            this.mv.visitLdcInsn(obj);
            return;
        }
        if (obj instanceof Long) {
            this.mv.visitLdcInsn(obj);
            wrapPrimitive(Long.TYPE);
            return;
        }
        if (obj instanceof Float) {
            this.mv.visitLdcInsn(obj);
            wrapPrimitive(Float.TYPE);
            return;
        }
        if (obj instanceof Double) {
            this.mv.visitLdcInsn(obj);
            wrapPrimitive(Double.TYPE);
            return;
        }
        if (obj instanceof Short) {
            this.mv.visitLdcInsn(obj);
            wrapPrimitive(Short.TYPE);
            return;
        }
        if (obj instanceof Character) {
            this.mv.visitLdcInsn(obj);
            wrapPrimitive(Character.TYPE);
        } else if (obj instanceof Boolean) {
            this.mv.visitLdcInsn(obj);
            wrapPrimitive(Boolean.TYPE);
        } else if (obj instanceof Byte) {
            this.mv.visitLdcInsn(obj);
            wrapPrimitive(Byte.TYPE);
        }
    }

    public static int toPrimitiveTypeOperand(Class<?> cls) {
        if (cls == Integer.TYPE) {
            return 10;
        }
        if (cls == Long.TYPE) {
            return 11;
        }
        if (cls == Double.TYPE) {
            return 7;
        }
        if (cls == Float.TYPE) {
            return 6;
        }
        if (cls == Short.TYPE) {
            return 9;
        }
        if (cls == Byte.TYPE) {
            return 8;
        }
        if (cls == Character.TYPE) {
            return 5;
        }
        if (cls == Boolean.TYPE) {
            return 4;
        }
        throw new IllegalStateException("Non-primitive type passed to toPrimitiveTypeOperand: " + cls);
    }

    private void createArray(Class cls, int i) {
        intPush(i);
        if (cls.isPrimitive()) {
            this.mv.visitIntInsn(Opcodes.NEWARRAY, toPrimitiveTypeOperand(cls));
        } else {
            this.mv.visitTypeInsn(Opcodes.ANEWARRAY, Type.getInternalName(cls));
        }
    }

    public void arrayStore(Class cls) {
        if (cls.isPrimitive()) {
            if (cls == Integer.TYPE) {
                this.mv.visitInsn(79);
                return;
            }
            if (cls == Character.TYPE) {
                this.mv.visitInsn(85);
                return;
            }
            if (cls == Boolean.TYPE) {
                this.mv.visitInsn(84);
                return;
            }
            if (cls == Double.TYPE) {
                this.mv.visitInsn(82);
                return;
            }
            if (cls == Float.TYPE) {
                this.mv.visitInsn(81);
                return;
            }
            if (cls == Short.TYPE) {
                this.mv.visitInsn(86);
                return;
            } else if (cls == Long.TYPE) {
                this.mv.visitInsn(80);
                return;
            } else {
                if (cls == Byte.TYPE) {
                    this.mv.visitInsn(84);
                    return;
                }
                return;
            }
        }
        this.mv.visitInsn(83);
    }

    public void wrapRuntimeConverstion(Class cls) {
        ldcClassConstant(getWrapperClass(cls));
        this.mv.visitMethodInsn(Opcodes.INVOKESTATIC, bIW.FRAGMENT_ENCODE_SET + NAMESPACE + "DataConversion", "convert", "(Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;");
    }

    private Object addSubstatement(ExecutableStatement executableStatement) {
        this.compiledInputs.add(executableStatement);
        this.mv.visitVarInsn(25, 0);
        MethodVisitor methodVisitor = this.mv;
        String str = this.className;
        StringBuilder sb = new StringBuilder();
        sb.append("p");
        sb.append(this.compiledInputs.size() - 1);
        methodVisitor.visitFieldInsn(Opcodes.GETFIELD, str, sb.toString(), "L" + NAMESPACE + "compiler/ExecutableStatement;");
        this.mv.visitVarInsn(25, 2);
        this.mv.visitVarInsn(25, 3);
        this.mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getInternalName(ExecutableStatement.class), "getValue", "(Ljava/lang/Object;L" + NAMESPACE + "integration/VariableResolverFactory;)Ljava/lang/Object;");
        return null;
    }

    private void loadVariableByName(String str) {
        this.mv.visitVarInsn(25, 3);
        this.mv.visitLdcInsn(str);
        this.mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, bIW.FRAGMENT_ENCODE_SET + NAMESPACE + "integration/VariableResolverFactory", "getVariableResolver", "(Ljava/lang/String;)L" + NAMESPACE + "integration/VariableResolver;");
        this.mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, bIW.FRAGMENT_ENCODE_SET + NAMESPACE + "integration/VariableResolver", "getValue", "()Ljava/lang/Object;");
        this.returnType = Object.class;
    }

    private void loadVariableByIndex(int i) {
        this.mv.visitVarInsn(25, 3);
        intPush(i);
        this.mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, bIW.FRAGMENT_ENCODE_SET + NAMESPACE + "integration/VariableResolverFactory", "getIndexedVariableResolver", "(I)L" + NAMESPACE + "integration/VariableResolver;");
        this.mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, bIW.FRAGMENT_ENCODE_SET + NAMESPACE + "integration/VariableResolver", "getValue", "()Ljava/lang/Object;");
        this.returnType = Object.class;
    }

    private void loadField(int i) {
        this.mv.visitVarInsn(25, 0);
        this.mv.visitFieldInsn(Opcodes.GETFIELD, this.className, "p" + i, "L" + NAMESPACE + "compiler/ExecutableStatement;");
    }

    private void ldcClassConstant(Class cls) {
        if (OPCODES_VERSION == 48) {
            this.mv.visitLdcInsn(cls.getName());
            this.mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;");
            Label label = new Label();
            this.mv.visitJumpInsn(Opcodes.GOTO, label);
            this.mv.visitTypeInsn(Opcodes.NEW, "java/lang/NoClassDefFoundError");
            this.mv.visitInsn(90);
            this.mv.visitInsn(95);
            this.mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Throwable", "getMessage", "()Ljava/lang/String;");
            this.mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/NoClassDefFoundError", "<init>", "(Ljava/lang/String;)V");
            this.mv.visitInsn(Opcodes.ATHROW);
            this.mv.visitLabel(label);
            return;
        }
        this.mv.visitLdcInsn(Type.getType((Class<?>) cls));
    }

    private void buildInputs() {
        if (this.compiledInputs.size() == 0) {
            return;
        }
        StringAppender stringAppender = new StringAppender("(");
        int size = this.compiledInputs.size();
        for (int i = 0; i < size; i++) {
            this.cw.visitField(2, "p" + i, "L" + NAMESPACE + "compiler/ExecutableStatement;", null, null).visitEnd();
            stringAppender.append("L" + NAMESPACE + "compiler/ExecutableStatement;");
        }
        stringAppender.append(")V");
        MethodVisitor visitMethod = this.cw.visitMethod(1, "<init>", stringAppender.toString(), null, null);
        visitMethod.visitCode();
        visitMethod.visitVarInsn(25, 0);
        visitMethod.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
        int i2 = 0;
        while (i2 < size) {
            visitMethod.visitVarInsn(25, 0);
            int i3 = i2 + 1;
            visitMethod.visitVarInsn(25, i3);
            visitMethod.visitFieldInsn(Opcodes.PUTFIELD, this.className, "p" + i2, "L" + NAMESPACE + "compiler/ExecutableStatement;");
            i2 = i3;
        }
        visitMethod.visitInsn(Opcodes.RETURN);
        visitMethod.visitMaxs(0, 0);
        visitMethod.visitEnd();
    }

    private int _getAccessor(Object obj, Class cls) {
        int i;
        Class<?> nonPrimitiveArray;
        if (obj instanceof List) {
            this.mv.visitTypeInsn(Opcodes.NEW, LIST_IMPL);
            this.mv.visitInsn(89);
            this.mv.visitInsn(89);
            List list = (List) obj;
            intPush(list.size());
            this.mv.visitMethodInsn(Opcodes.INVOKESPECIAL, LIST_IMPL, "<init>", "(I)V");
            Iterator it = list.iterator();
            while (it.hasNext()) {
                if (_getAccessor(it.next(), cls) != 3) {
                    this.mv.visitInsn(87);
                }
                this.mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List", "add", "(Ljava/lang/Object;)Z");
                this.mv.visitInsn(87);
                this.mv.visitInsn(89);
            }
            this.returnType = List.class;
            return 1;
        }
        if (obj instanceof Map) {
            this.mv.visitTypeInsn(Opcodes.NEW, MAP_IMPL);
            this.mv.visitInsn(89);
            this.mv.visitInsn(89);
            Map map = (Map) obj;
            intPush(map.size());
            this.mv.visitMethodInsn(Opcodes.INVOKESPECIAL, MAP_IMPL, "<init>", "(I)V");
            for (Object obj2 : map.keySet()) {
                this.mv.visitTypeInsn(Opcodes.CHECKCAST, "java/util/Map");
                if (_getAccessor(obj2, cls) != 3) {
                    this.mv.visitInsn(87);
                }
                if (_getAccessor(map.get(obj2), cls) != 3) {
                    this.mv.visitInsn(87);
                }
                this.mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
                this.mv.visitInsn(87);
                this.mv.visitInsn(89);
            }
            this.returnType = Map.class;
            return 2;
        }
        if (obj instanceof Object[]) {
            Accessor[] accessorArr = new Accessor[((Object[]) obj).length];
            if (cls != null) {
                i = 0;
                while (cls.getName().charAt(i) == '[') {
                    i++;
                }
            } else {
                cls = Object[].class;
                i = 1;
            }
            try {
                Class subComponentType = ParseTools.getSubComponentType(cls);
                createArray(subComponentType, ((Object[]) obj).length);
                if (i > 1) {
                    nonPrimitiveArray = ParseTools.findClass(null, ParseTools.repeatChar('[', i - 1) + "L" + ParseTools.getBaseComponentType(cls).getName() + ";", this.pCtx);
                } else {
                    nonPrimitiveArray = ReflectionUtil.toNonPrimitiveArray(cls);
                }
                this.mv.visitInsn(89);
                int i2 = 0;
                for (Object obj3 : (Object[]) obj) {
                    intPush(i2);
                    if (_getAccessor(obj3, nonPrimitiveArray) != 3) {
                        this.mv.visitInsn(87);
                    }
                    if (subComponentType.isPrimitive()) {
                        unwrapPrimitive(subComponentType);
                    }
                    arrayStore(subComponentType);
                    this.mv.visitInsn(89);
                    i2++;
                }
                return 0;
            } catch (ClassNotFoundException e) {
                throw new RuntimeException("this error should never throw:" + ParseTools.getBaseComponentType(cls).getName(), e);
            }
        }
        if (cls.isArray()) {
            writeLiteralOrSubexpression(ParseTools.subCompileExpression(((String) obj).toCharArray(), this.pCtx), ParseTools.getSubComponentType(cls));
        } else {
            writeLiteralOrSubexpression(ParseTools.subCompileExpression(((String) obj).toCharArray(), this.pCtx));
        }
        return 3;
    }

    private Class writeLiteralOrSubexpression(Object obj) {
        return writeLiteralOrSubexpression(obj, null, null);
    }

    private Class writeLiteralOrSubexpression(Object obj, Class cls) {
        return writeLiteralOrSubexpression(obj, cls, null);
    }

    private Class writeLiteralOrSubexpression(Object obj, Class cls, Class cls2) {
        Class cls3;
        if (obj instanceof ExecutableLiteral) {
            ExecutableLiteral executableLiteral = (ExecutableLiteral) obj;
            Object literal = executableLiteral.getLiteral();
            if (literal == null) {
                this.mv.visitInsn(1);
                return null;
            }
            Class<?> cls4 = literal.getClass();
            if (cls4 == Integer.class && cls == (cls3 = Integer.TYPE)) {
                intPush(executableLiteral.getInteger32());
                return cls3;
            }
            if (cls != null && cls != cls4) {
                if (!DataConversion.canConvert(cls4, cls)) {
                    throw new CompileException("was expecting type: " + cls.getName() + "; but found type: " + cls4.getName(), this.expr, this.st);
                }
                writeOutLiteralWrapped(DataConversion.convert(literal, cls));
                return cls4;
            }
            writeOutLiteralWrapped(literal);
            return cls4;
        }
        this.literal = $assertionsDisabled;
        ExecutableStatement executableStatement = (ExecutableStatement) obj;
        addSubstatement(executableStatement);
        if (cls2 == null) {
            cls2 = executableStatement.getKnownEgressType();
        }
        if (cls != null && cls2 != cls && cls.isPrimitive()) {
            if (cls2 == null) {
                throw new OptimizationFailure("cannot optimize expression: " + new String(this.expr) + ": cannot determine ingress type for primitive output");
            }
            checkcast(cls2);
            unwrapPrimitive(cls);
        }
        return cls2;
    }

    private void addPrintOut(String str) {
        this.mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
        this.mv.visitLdcInsn(str);
        this.mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
    }

    @Override
    public Accessor optimizeCollection(ParserContext parserContext, Object obj, Class cls, char[] cArr, int i, int i2, Object obj2, Object obj3, VariableResolverFactory variableResolverFactory) {
        int i3;
        this.expr = cArr;
        this.start = i;
        this.cursor = i;
        this.end = i + i2;
        this.length = i2;
        this.returnType = cls;
        this.compiledInputs = new ArrayList<>();
        this.ctx = obj2;
        this.thisRef = obj3;
        this.variableFactory = variableResolverFactory;
        this.pCtx = parserContext;
        _initJIT();
        this.literal = true;
        _getAccessor(obj, cls);
        _finishJIT();
        try {
            Accessor _initializeAccessor = _initializeAccessor();
            return (cArr == null || (i3 = this.length) <= i) ? _initializeAccessor : new Union(parserContext, _initializeAccessor, cArr, i, i3);
        } catch (Exception e) {
            throw new OptimizationFailure("could not optimize collection", e);
        }
    }

    private void checkcast(Class cls) {
        this.mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(cls));
    }

    private void intPush(int i) {
        if (i < 0 || i >= 6) {
            if (i > -127 && i < 128) {
                this.mv.visitIntInsn(16, i);
                return;
            } else if (i > 32767) {
                this.mv.visitLdcInsn(Integer.valueOf(i));
                return;
            } else {
                this.mv.visitIntInsn(17, i);
                return;
            }
        }
        if (i == 0) {
            this.mv.visitInsn(3);
            return;
        }
        if (i == 1) {
            this.mv.visitInsn(4);
            return;
        }
        if (i == 2) {
            this.mv.visitInsn(5);
            return;
        }
        if (i == 3) {
            this.mv.visitInsn(6);
        } else if (i == 4) {
            this.mv.visitInsn(7);
        } else {
            if (i != 5) {
                return;
            }
            this.mv.visitInsn(8);
        }
    }

    @Override
    public Accessor optimizeObjectCreation(ParserContext parserContext, char[] cArr, int i, int i2, Object obj, Object obj2, VariableResolverFactory variableResolverFactory) {
        String str;
        String str2;
        Object[] objArr;
        char[] cArr2 = cArr;
        _initJIT();
        this.compiledInputs = new ArrayList<>();
        this.cursor = i;
        this.start = i;
        int i3 = i + i2;
        this.end = i3;
        this.length = i3 - i;
        this.ctx = obj;
        this.thisRef = obj2;
        this.variableFactory = variableResolverFactory;
        this.pCtx = parserContext;
        String[] captureContructorAndResidual = ParseTools.captureContructorAndResidual(cArr, i, i2);
        List<char[]> parseMethodOrConstructor = ParseTools.parseMethodOrConstructor(captureContructorAndResidual[0].toCharArray());
        int i4 = 89;
        try {
            try {
                if (parseMethodOrConstructor != null) {
                    Iterator<char[]> it = parseMethodOrConstructor.iterator();
                    while (it.hasNext()) {
                        this.compiledInputs.add((ExecutableStatement) ParseTools.subCompileExpression(it.next(), parserContext));
                    }
                    Class findClass = ParseTools.findClass(variableResolverFactory, new String(ParseTools.subset(cArr2, 0, ArrayTools.findFirst('(', i, this.length, cArr2))), parserContext);
                    this.mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(findClass));
                    this.mv.visitInsn(89);
                    int size = parseMethodOrConstructor.size();
                    Object[] objArr2 = new Object[size];
                    Iterator<ExecutableStatement> it2 = this.compiledInputs.iterator();
                    int i5 = 0;
                    while (it2.hasNext()) {
                        objArr2[i5] = it2.next().getValue(obj, variableResolverFactory);
                        i5++;
                    }
                    Constructor bestConstructorCandidate = ParseTools.getBestConstructorCandidate(objArr2, findClass, parserContext.isStrongTyping());
                    if (bestConstructorCandidate == null) {
                        StringBuilder sb = new StringBuilder();
                        int i6 = 0;
                        while (i6 < size) {
                            sb.append(objArr2[i6].getClass().getName());
                            i6++;
                            if (i6 < size) {
                                sb.append(", ");
                            }
                        }
                        throw new CompileException("unable to find constructor: " + findClass.getName() + "(" + sb.toString() + ")", this.expr, this.st);
                    }
                    this.returnType = bestConstructorCandidate.getDeclaringClass();
                    Class<?>[] parameterTypes = bestConstructorCandidate.getParameterTypes();
                    Class<?> cls = null;
                    int i7 = -1;
                    int i8 = 0;
                    while (i8 < parseMethodOrConstructor.size()) {
                        if (i8 < parameterTypes.length) {
                            cls = parameterTypes[i8];
                            if (bestConstructorCandidate.isVarArgs() && i8 == parameterTypes.length - 1) {
                                cls = ParseTools.getBaseComponentType(cls);
                                createArray(cls, parseMethodOrConstructor.size() - i8);
                                i7 = i8;
                            }
                        } else if (i7 < 0 || cls == null) {
                            throw new IllegalStateException("Incorrect argument count " + i8);
                        }
                        if (i7 >= 0) {
                            this.mv.visitInsn(i4);
                            intPush(i8 - i7);
                        }
                        List<char[]> list = parseMethodOrConstructor;
                        this.mv.visitVarInsn(25, 0);
                        this.mv.visitFieldInsn(Opcodes.GETFIELD, this.className, "p" + i8, "L" + NAMESPACE + "compiler/ExecutableStatement;");
                        this.mv.visitVarInsn(25, 2);
                        this.mv.visitVarInsn(25, 3);
                        this.mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, bIW.FRAGMENT_ENCODE_SET + NAMESPACE + "compiler/ExecutableStatement", "getValue", "(Ljava/lang/Object;L" + NAMESPACE + "integration/VariableResolverFactory;)Ljava/lang/Object;");
                        Class<?> wrapperClass = cls.isPrimitive() ? getWrapperClass(cls) : cls;
                        Object obj3 = objArr2[i8];
                        if (obj3 != null && !obj3.getClass().isAssignableFrom(cls)) {
                            ldcClassConstant(wrapperClass);
                            objArr = objArr2;
                            this.mv.visitMethodInsn(Opcodes.INVOKESTATIC, bIW.FRAGMENT_ENCODE_SET + NAMESPACE + "DataConversion", "convert", "(Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;");
                            if (cls.isPrimitive()) {
                                unwrapPrimitive(cls);
                            } else {
                                this.mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(wrapperClass));
                            }
                        } else {
                            objArr = objArr2;
                            this.mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(cls));
                        }
                        if (i7 >= 0) {
                            arrayStore(cls);
                        }
                        i8++;
                        parseMethodOrConstructor = list;
                        objArr2 = objArr;
                        i4 = 89;
                    }
                    if (i8 < parameterTypes.length && bestConstructorCandidate.isVarArgs()) {
                        createArray(ParseTools.getBaseComponentType(parameterTypes[i8]), 0);
                    }
                    this.mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(findClass), "<init>", Type.getConstructorDescriptor(bestConstructorCandidate));
                    _finishJIT();
                    Accessor _initializeAccessor = _initializeAccessor();
                    return (captureContructorAndResidual.length <= 1 || (str2 = captureContructorAndResidual[1]) == null || str2.trim().equals(bIW.FRAGMENT_ENCODE_SET)) ? _initializeAccessor : new Union(parserContext, _initializeAccessor, captureContructorAndResidual[1].toCharArray(), 0, captureContructorAndResidual[1].length());
                }
                Class findClass2 = ParseTools.findClass(variableResolverFactory, new String(cArr), parserContext);
                this.mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(findClass2));
                this.mv.visitInsn(89);
                this.mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(findClass2), "<init>", Type.getConstructorDescriptor(findClass2.getConstructor(EMPTYCLS)));
                _finishJIT();
                Accessor _initializeAccessor2 = _initializeAccessor();
                return (captureContructorAndResidual.length <= 1 || (str = captureContructorAndResidual[1]) == null || str.trim().equals(bIW.FRAGMENT_ENCODE_SET)) ? _initializeAccessor2 : new Union(parserContext, _initializeAccessor2, captureContructorAndResidual[1].toCharArray(), 0, captureContructorAndResidual[1].length());
            } catch (ClassNotFoundException unused) {
                cArr2 = cArr;
                throw new CompileException("class or class reference not found: " + new String(cArr2), cArr2, this.st);
            } catch (Exception e) {
                e = e;
                cArr2 = cArr;
                throw new OptimizationFailure("could not optimize construtor: " + new String(cArr2), e);
            }
        } catch (ClassNotFoundException unused2) {
            throw new CompileException("class or class reference not found: " + new String(cArr2), cArr2, this.st);
        } catch (Exception e2) {
            e = e2;
            throw new OptimizationFailure("could not optimize construtor: " + new String(cArr2), e);
        }
    }

    @Override
    public Class getEgressType() {
        return this.returnType;
    }

    private void dumpAdvancedDebugging() {
        if (this.buildLog == null) {
            return;
        }
        PrintStream printStream = System.out;
        StringBuilder sb = new StringBuilder();
        sb.append("JIT Compiler Dump for: <<");
        char[] cArr = this.expr;
        sb.append(cArr == null ? null : new String(cArr));
        sb.append(">>\n-------------------------------\n");
        printStream.println(sb.toString());
        printStream.println(this.buildLog.toString());
        printStream.println("\n<END OF DUMP>\n");
        if (MVEL.isFileDebugging()) {
            try {
                FileWriter debugFileWriter = ParseTools.getDebugFileWriter();
                debugFileWriter.write(this.buildLog.toString());
                debugFileWriter.flush();
                debugFileWriter.close();
            } catch (IOException unused) {
            }
        }
    }

    private Object propHandlerByteCode(String str, Object obj, Class cls) {
        PropertyHandler propertyHandler = PropertyHandlerFactory.getPropertyHandler(cls);
        if (propertyHandler instanceof ProducesBytecode) {
            ((ProducesBytecode) propertyHandler).produceBytecodeGet(this.mv, str, this.variableFactory);
            return propertyHandler.getProperty(str, obj, this.variableFactory);
        }
        throw new RuntimeException("unable to compileShared: custom accessor does not support producing bytecode: " + propertyHandler.getClass().getName());
    }

    private void propHandlerByteCodePut(String str, Object obj, Class cls, Object obj2) {
        PropertyHandler propertyHandler = PropertyHandlerFactory.getPropertyHandler(cls);
        if (propertyHandler instanceof ProducesBytecode) {
            ((ProducesBytecode) propertyHandler).produceBytecodePut(this.mv, str, this.variableFactory);
            propertyHandler.setProperty(str, obj, this.variableFactory, obj2);
        } else {
            throw new RuntimeException("unable to compileShared: custom accessor does not support producing bytecode: " + propertyHandler.getClass().getName());
        }
    }

    private void writeOutNullHandler(Member member, int i) {
        this.mv.visitInsn(89);
        Label label = new Label();
        this.mv.visitJumpInsn(Opcodes.IFNONNULL, label);
        this.mv.visitInsn(87);
        this.mv.visitVarInsn(25, 0);
        if (i == 0) {
            this.propNull = true;
            this.mv.visitFieldInsn(Opcodes.GETFIELD, this.className, "nullPropertyHandler", "L" + NAMESPACE + "integration/PropertyHandler;");
        } else {
            this.methNull = true;
            this.mv.visitFieldInsn(Opcodes.GETFIELD, this.className, "nullMethodHandler", "L" + NAMESPACE + "integration/PropertyHandler;");
        }
        this.mv.visitLdcInsn(member.getName());
        this.mv.visitVarInsn(25, 1);
        this.mv.visitVarInsn(25, 3);
        this.mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, NAMESPACE + "integration/PropertyHandler", "getProperty", "(Ljava/lang/String;Ljava/lang/Object;L" + NAMESPACE + "integration/VariableResolverFactory;)Ljava/lang/Object;");
        this.mv.visitLabel(label);
    }

    @Override
    public boolean isLiteralOnly() {
        return this.literal;
    }
}