Search in sources :

Example 1 with ExecutableStatement

use of org.mvel2.compiler.ExecutableStatement in project mvel by mikebrock.

the class ASMAccessorOptimizer method optimizeCollection.

public Accessor optimizeCollection(ParserContext pCtx, Object o, Class type, char[] property, int start, int offset, Object ctx, Object thisRef, VariableResolverFactory factory) {
    this.expr = property;
    this.cursor = this.start = start;
    this.end = start + offset;
    this.length = offset;
    this.returnType = type;
    this.compiledInputs = new ArrayList<ExecutableStatement>();
    this.ctx = ctx;
    this.thisRef = thisRef;
    this.variableFactory = factory;
    _initJIT();
    literal = true;
    _getAccessor(o, type);
    _finishJIT();
    try {
        Accessor compiledAccessor = _initializeAccessor();
        if (property != null && length > start) {
            return new Union(compiledAccessor, property, start, length);
        } else {
            return compiledAccessor;
        }
    } catch (Exception e) {
        throw new OptimizationFailure("could not optimize collection", e);
    }
}
Also used : PropertyTools.getFieldOrWriteAccessor(org.mvel2.util.PropertyTools.getFieldOrWriteAccessor) PropertyTools.getFieldOrAccessor(org.mvel2.util.PropertyTools.getFieldOrAccessor) Union(org.mvel2.optimizers.impl.refl.nodes.Union) IOException(java.io.IOException)

Example 2 with ExecutableStatement

use of org.mvel2.compiler.ExecutableStatement in project mvel by mikebrock.

the class ASMAccessorOptimizer method getCollectionPropertyAO.

private Object getCollectionPropertyAO(Object ctx, String prop) throws IllegalAccessException, InvocationTargetException {
    if (prop.length() > 0) {
        ctx = getBeanProperty(ctx, prop);
        first = false;
    }
    if (ctx == null)
        return null;
    assert debug("\n  **  ENTER -> {collection:<<" + prop + ">>; ctx=" + ctx + "}");
    int _start = ++cursor;
    skipWhitespace();
    if (cursor == end)
        throw new CompileException("unterminated '['", expr, st);
    if (scanTo(']'))
        throw new CompileException("unterminated '['", expr, st);
    String tk = new String(expr, _start, cursor - _start);
    assert debug("{collection token:<<" + tk + ">>}");
    ExecutableStatement compiled = (ExecutableStatement) subCompileExpression(tk.toCharArray());
    Object item = compiled.getValue(ctx, variableFactory);
    ++cursor;
    if (ctx instanceof Map) {
        if (hasPropertyHandler(Map.class)) {
            return propHandlerByteCode(tk, ctx, Map.class);
        } else {
            if (first) {
                assert debug("ALOAD 1");
                mv.visitVarInsn(ALOAD, 1);
            }
            assert debug("CHECKCAST java/util/Map");
            mv.visitTypeInsn(CHECKCAST, "java/util/Map");
            Class c = writeLiteralOrSubexpression(compiled);
            if (c != null && c.isPrimitive()) {
                wrapPrimitive(c);
            }
            assert debug("INVOKEINTERFACE: Map.get");
            mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
        }
        return ((Map) ctx).get(item);
    } else if (ctx instanceof List) {
        if (hasPropertyHandler(List.class)) {
            return propHandlerByteCode(tk, ctx, List.class);
        } else {
            if (first) {
                assert debug("ALOAD 1");
                mv.visitVarInsn(ALOAD, 1);
            }
            assert debug("CHECKCAST java/util/List");
            mv.visitTypeInsn(CHECKCAST, "java/util/List");
            writeLiteralOrSubexpression(compiled, int.class);
            assert debug("INVOKEINTERFACE: java/util/List.get");
            mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "get", "(I)Ljava/lang/Object;");
            return ((List) ctx).get(convert(item, Integer.class));
        }
    } else if (ctx.getClass().isArray()) {
        if (hasPropertyHandler(Array.class)) {
            return propHandlerByteCode(tk, ctx, Array.class);
        } else {
            if (first) {
                assert debug("ALOAD 1");
                mv.visitVarInsn(ALOAD, 1);
            }
            assert debug("CHECKCAST " + getDescriptor(ctx.getClass()));
            mv.visitTypeInsn(CHECKCAST, getDescriptor(ctx.getClass()));
            writeLiteralOrSubexpression(compiled, int.class, item.getClass());
            Class cls = getBaseComponentType(ctx.getClass());
            if (cls.isPrimitive()) {
                if (cls == int.class) {
                    assert debug("IALOAD");
                    mv.visitInsn(IALOAD);
                } else if (cls == char.class) {
                    assert debug("CALOAD");
                    mv.visitInsn(CALOAD);
                } else if (cls == boolean.class) {
                    assert debug("BALOAD");
                    mv.visitInsn(BALOAD);
                } else if (cls == double.class) {
                    assert debug("DALOAD");
                    mv.visitInsn(DALOAD);
                } else if (cls == float.class) {
                    assert debug("FALOAD");
                    mv.visitInsn(FALOAD);
                } else if (cls == short.class) {
                    assert debug("SALOAD");
                    mv.visitInsn(SALOAD);
                } else if (cls == long.class) {
                    assert debug("LALOAD");
                    mv.visitInsn(LALOAD);
                } else if (cls == byte.class) {
                    assert debug("BALOAD");
                    mv.visitInsn(BALOAD);
                }
                wrapPrimitive(cls);
            } else {
                assert debug("AALOAD");
                mv.visitInsn(AALOAD);
            }
            return Array.get(ctx, convert(item, Integer.class));
        }
    } else if (ctx instanceof CharSequence) {
        if (hasPropertyHandler(CharSequence.class)) {
            return propHandlerByteCode(tk, ctx, CharSequence.class);
        } else {
            if (first) {
                assert debug("ALOAD 1");
                mv.visitVarInsn(ALOAD, 1);
            }
            assert debug("CHECKCAST java/lang/CharSequence");
            mv.visitTypeInsn(CHECKCAST, "java/lang/CharSequence");
            if (item instanceof Integer) {
                intPush((Integer) item);
                assert debug("INVOKEINTERFACE java/lang/CharSequence.charAt");
                mv.visitMethodInsn(INVOKEINTERFACE, "java/lang/CharSequence", "charAt", "(I)C");
                wrapPrimitive(char.class);
                return ((CharSequence) ctx).charAt((Integer) item);
            } else {
                writeLiteralOrSubexpression(compiled, Integer.class);
                unwrapPrimitive(int.class);
                assert debug("INVOKEINTERFACE java/lang/CharSequence.charAt");
                mv.visitMethodInsn(INVOKEINTERFACE, "java/lang/CharSequence", "charAt", "(I)C");
                wrapPrimitive(char.class);
                return ((CharSequence) ctx).charAt(convert(item, Integer.class));
            }
        }
    } else {
        TypeDescriptor tDescr = new TypeDescriptor(expr, start, end - start, 0);
        if (tDescr.isArray()) {
            try {
                Class cls = getClassReference((Class) ctx, tDescr, variableFactory, pCtx);
                //   rootNode = new StaticReferenceAccessor(cls);
                ldcClassConstant(cls);
                return cls;
            } catch (Exception e) {
            //fall through
            }
        }
        throw new CompileException("illegal use of []: unknown type: " + (ctx == null ? null : ctx.getClass().getName()), expr, st);
    }
}
Also used : TypeDescriptor(org.mvel2.ast.TypeDescriptor) ArrayList(java.util.ArrayList) List(java.util.List) Map(java.util.Map) IOException(java.io.IOException)

Example 3 with ExecutableStatement

use of org.mvel2.compiler.ExecutableStatement in project mvel by mikebrock.

the class ASMAccessorOptimizer method buildInputs.

private void buildInputs() {
    if (compiledInputs.size() == 0)
        return;
    assert debug("\n{SETTING UP MEMBERS...}\n");
    StringAppender constSig = new StringAppender("(");
    int size = compiledInputs.size();
    for (int i = 0; i < size; i++) {
        assert debug("ACC_PRIVATE p" + i);
        cw.visitField(ACC_PRIVATE, "p" + i, "L" + NAMESPACE + "compiler/ExecutableStatement;", null, null).visitEnd();
        constSig.append("L" + NAMESPACE + "compiler/ExecutableStatement;");
    }
    constSig.append(")V");
    assert debug("\n{CREATING INJECTION CONSTRUCTOR}\n");
    MethodVisitor cv = cw.visitMethod(ACC_PUBLIC, "<init>", constSig.toString(), null, null);
    cv.visitCode();
    assert debug("ALOAD 0");
    cv.visitVarInsn(ALOAD, 0);
    assert debug("INVOKESPECIAL java/lang/Object.<init>");
    cv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
    for (int i = 0; i < size; i++) {
        assert debug("ALOAD 0");
        cv.visitVarInsn(ALOAD, 0);
        assert debug("ALOAD " + (i + 1));
        cv.visitVarInsn(ALOAD, i + 1);
        assert debug("PUTFIELD p" + i);
        cv.visitFieldInsn(PUTFIELD, className, "p" + i, "L" + NAMESPACE + "compiler/ExecutableStatement;");
    }
    assert debug("RETURN");
    cv.visitInsn(RETURN);
    cv.visitMaxs(0, 0);
    cv.visitEnd();
    assert debug("}");
}
Also used : MethodVisitor(org.mvel2.asm.MethodVisitor)

Example 4 with ExecutableStatement

use of org.mvel2.compiler.ExecutableStatement in project mvel by mikebrock.

the class ASMAccessorOptimizer method optimizeObjectCreation.

public Accessor optimizeObjectCreation(ParserContext pCtx, char[] property, int start, int offset, Object ctx, Object thisRef, VariableResolverFactory factory) {
    _initJIT();
    compiledInputs = new ArrayList<ExecutableStatement>();
    this.start = cursor = start;
    this.end = start + offset;
    this.length = this.end - this.start;
    this.ctx = ctx;
    this.thisRef = thisRef;
    this.variableFactory = factory;
    this.pCtx = pCtx;
    String[] cnsRes = captureContructorAndResidual(property, start, offset);
    List<char[]> constructorParms = parseMethodOrConstructor(cnsRes[0].toCharArray());
    try {
        if (constructorParms != null) {
            for (char[] constructorParm : constructorParms) {
                compiledInputs.add((ExecutableStatement) subCompileExpression(constructorParm, pCtx));
            }
            Class cls = findClass(factory, new String(subset(property, 0, findFirst('(', start, length, property))), pCtx);
            assert debug("NEW " + getInternalName(cls));
            mv.visitTypeInsn(NEW, getInternalName(cls));
            assert debug("DUP");
            mv.visitInsn(DUP);
            Object[] parms = new Object[constructorParms.size()];
            int i = 0;
            for (ExecutableStatement es : compiledInputs) {
                parms[i++] = es.getValue(ctx, factory);
            }
            Constructor cns = getBestConstructorCandidate(parms, cls, pCtx.isStrongTyping());
            if (cns == null) {
                StringBuilder error = new StringBuilder();
                for (int x = 0; x < parms.length; x++) {
                    error.append(parms[x].getClass().getName());
                    if (x + 1 < parms.length)
                        error.append(", ");
                }
                throw new CompileException("unable to find constructor: " + cls.getName() + "(" + error.toString() + ")", expr, st);
            }
            this.returnType = cns.getDeclaringClass();
            Class tg;
            for (i = 0; i < constructorParms.size(); i++) {
                assert debug("ALOAD 0");
                mv.visitVarInsn(ALOAD, 0);
                assert debug("GETFIELD p" + i);
                mv.visitFieldInsn(GETFIELD, className, "p" + i, "L" + NAMESPACE + "compiler/ExecutableStatement;");
                assert debug("ALOAD 2");
                mv.visitVarInsn(ALOAD, 2);
                assert debug("ALOAD 3");
                mv.visitVarInsn(ALOAD, 3);
                assert debug("INVOKEINTERFACE " + NAMESPACE + "compiler/ExecutableStatement.getValue");
                mv.visitMethodInsn(INVOKEINTERFACE, "" + NAMESPACE + "compiler/ExecutableStatement", "getValue", "(Ljava/lang/Object;L" + NAMESPACE + "integration/VariableResolverFactory;)Ljava/lang/Object;");
                tg = cns.getParameterTypes()[i].isPrimitive() ? getWrapperClass(cns.getParameterTypes()[i]) : cns.getParameterTypes()[i];
                if (parms[i] != null && !parms[i].getClass().isAssignableFrom(cns.getParameterTypes()[i])) {
                    ldcClassConstant(tg);
                    assert debug("INVOKESTATIC " + NAMESPACE + "DataConversion.convert");
                    mv.visitMethodInsn(INVOKESTATIC, "" + NAMESPACE + "DataConversion", "convert", "(Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;");
                    if (cns.getParameterTypes()[i].isPrimitive()) {
                        unwrapPrimitive(cns.getParameterTypes()[i]);
                    } else {
                        assert debug("CHECKCAST " + getInternalName(tg));
                        mv.visitTypeInsn(CHECKCAST, getInternalName(tg));
                    }
                } else {
                    assert debug("CHECKCAST " + getInternalName(cns.getParameterTypes()[i]));
                    mv.visitTypeInsn(CHECKCAST, getInternalName(cns.getParameterTypes()[i]));
                }
            }
            assert debug("INVOKESPECIAL " + getInternalName(cls) + ".<init> : " + getConstructorDescriptor(cns));
            mv.visitMethodInsn(INVOKESPECIAL, getInternalName(cls), "<init>", getConstructorDescriptor(cns));
            _finishJIT();
            Accessor acc = _initializeAccessor();
            if (cnsRes.length > 1 && cnsRes[1] != null && !cnsRes[1].trim().equals("")) {
                return new Union(acc, cnsRes[1].toCharArray(), 0, cnsRes[1].length());
            }
            return acc;
        } else {
            Class cls = findClass(factory, new String(property), pCtx);
            assert debug("NEW " + getInternalName(cls));
            mv.visitTypeInsn(NEW, getInternalName(cls));
            assert debug("DUP");
            mv.visitInsn(DUP);
            Constructor cns = cls.getConstructor(EMPTYCLS);
            assert debug("INVOKESPECIAL <init>");
            mv.visitMethodInsn(INVOKESPECIAL, getInternalName(cls), "<init>", getConstructorDescriptor(cns));
            _finishJIT();
            Accessor acc = _initializeAccessor();
            if (cnsRes.length > 1 && cnsRes[1] != null && !cnsRes[1].trim().equals("")) {
                return new Union(acc, cnsRes[1].toCharArray(), 0, cnsRes[1].length());
            }
            return acc;
        }
    } catch (ClassNotFoundException e) {
        throw new CompileException("class or class reference not found: " + new String(property), property, st);
    } catch (Exception e) {
        throw new OptimizationFailure("could not optimize construtor: " + new String(property), e);
    }
}
Also used : PropertyTools.getFieldOrWriteAccessor(org.mvel2.util.PropertyTools.getFieldOrWriteAccessor) PropertyTools.getFieldOrAccessor(org.mvel2.util.PropertyTools.getFieldOrAccessor) Union(org.mvel2.optimizers.impl.refl.nodes.Union) IOException(java.io.IOException)

Example 5 with ExecutableStatement

use of org.mvel2.compiler.ExecutableStatement in project mvel by mikebrock.

the class ReflectiveAccessorOptimizer method getCollectionProperty.

/**
   * Handle accessing a property embedded in a collections, map, or array
   *
   * @param ctx  -
   * @param prop -
   * @return -
   * @throws Exception -
   */
private Object getCollectionProperty(Object ctx, String prop) throws Exception {
    if (prop.length() > 0) {
        ctx = getBeanProperty(ctx, prop);
    }
    if (ctx == null)
        return null;
    int start = ++cursor;
    skipWhitespace();
    if (cursor == end)
        throw new CompileException("unterminated '['", this.expr, this.start);
    String item;
    if (scanTo(']'))
        throw new CompileException("unterminated '['", this.expr, this.start);
    item = new String(expr, start, cursor - start);
    boolean itemSubExpr = true;
    Object idx = null;
    try {
        idx = parseInt(item);
        itemSubExpr = false;
    } catch (Exception e) {
    // not a number;
    }
    ExecutableStatement itemStmt = null;
    if (itemSubExpr) {
        try {
            idx = (itemStmt = (ExecutableStatement) subCompileExpression(item.toCharArray(), pCtx)).getValue(ctx, thisRef, variableFactory);
        } catch (CompileException e) {
            e.setExpr(this.expr);
            e.setCursor(start);
            throw e;
        }
    }
    ++cursor;
    if (ctx instanceof Map) {
        if (itemSubExpr) {
            addAccessorNode(new MapAccessorNest(itemStmt, null));
        } else {
            addAccessorNode(new MapAccessor(parseInt(item)));
        }
        return ((Map) ctx).get(idx);
    } else if (ctx instanceof List) {
        if (itemSubExpr) {
            addAccessorNode(new ListAccessorNest(itemStmt, null));
        } else {
            addAccessorNode(new ListAccessor(parseInt(item)));
        }
        return ((List) ctx).get((Integer) idx);
    } else if (ctx.getClass().isArray()) {
        if (itemSubExpr) {
            addAccessorNode(new ArrayAccessorNest(itemStmt));
        } else {
            addAccessorNode(new ArrayAccessor(parseInt(item)));
        }
        return Array.get(ctx, (Integer) idx);
    } else if (ctx instanceof CharSequence) {
        if (itemSubExpr) {
            addAccessorNode(new IndexedCharSeqAccessorNest(itemStmt));
        } else {
            addAccessorNode(new IndexedCharSeqAccessor(parseInt(item)));
        }
        return ((CharSequence) ctx).charAt((Integer) idx);
    } else {
        TypeDescriptor tDescr = new TypeDescriptor(expr, this.start, length, 0);
        if (tDescr.isArray()) {
            Class cls = getClassReference((Class) ctx, tDescr, variableFactory, pCtx);
            rootNode = new StaticReferenceAccessor(cls);
            return cls;
        }
        throw new CompileException("illegal use of []: unknown type: " + ctx.getClass().getName(), this.expr, this.start);
    }
}
Also used : ExecutableStatement(org.mvel2.compiler.ExecutableStatement) TypeDescriptor(org.mvel2.ast.TypeDescriptor) List(java.util.List) Map(java.util.Map) WeakHashMap(java.util.WeakHashMap)

Aggregations

ExecutableStatement (org.mvel2.compiler.ExecutableStatement)25 IOException (java.io.IOException)6 ParserContext (org.mvel2.ParserContext)6 List (java.util.List)5 Map (java.util.Map)5 CompileException (org.mvel2.CompileException)4 TypeDescriptor (org.mvel2.ast.TypeDescriptor)4 ArrayList (java.util.ArrayList)3 ParserConfiguration (org.mvel2.ParserConfiguration)3 WeakHashMap (java.util.WeakHashMap)2 Union (org.mvel2.optimizers.impl.refl.nodes.Union)2 PropertyTools.getFieldOrAccessor (org.mvel2.util.PropertyTools.getFieldOrAccessor)2 PropertyTools.getFieldOrWriteAccessor (org.mvel2.util.PropertyTools.getFieldOrWriteAccessor)2 HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 Label (org.mvel2.asm.Label)1 MethodVisitor (org.mvel2.asm.MethodVisitor)1 EndOfStatement (org.mvel2.ast.EndOfStatement)1 Function (org.mvel2.ast.Function)1 Proto (org.mvel2.ast.Proto)1