Search in sources :

Example 6 with AccessorNode

use of org.mule.mvel2.compiler.AccessorNode in project mvel by mikebrock.

the class ReflectiveAccessorOptimizer method compileConstructor.

@SuppressWarnings({ "WeakerAccess" })
public AccessorNode compileConstructor(char[] expression, Object ctx, VariableResolverFactory vars) throws InstantiationException, IllegalAccessException, InvocationTargetException, ClassNotFoundException, NoSuchMethodException {
    String[] cnsRes = captureContructorAndResidual(expression, start, length);
    List<char[]> constructorParms = parseMethodOrConstructor(cnsRes[0].toCharArray());
    if (constructorParms != null) {
        String s = new String(subset(expression, 0, ArrayTools.findFirst('(', start, length, expression)));
        Class cls = ParseTools.findClass(vars, s, pCtx);
        ExecutableStatement[] cStmts = new ExecutableStatement[constructorParms.size()];
        for (int i = 0; i < constructorParms.size(); i++) {
            cStmts[i] = (ExecutableStatement) subCompileExpression(constructorParms.get(i), pCtx);
        }
        Object[] parms = new Object[constructorParms.size()];
        for (int i = 0; i < constructorParms.size(); i++) {
            parms[i] = cStmts[i].getValue(ctx, vars);
        }
        Constructor cns = getBestConstructorCandidate(parms, cls, pCtx.isStrongTyping());
        if (cns == null) {
            StringBuilder error = new StringBuilder();
            for (int i = 0; i < parms.length; i++) {
                error.append(parms[i].getClass().getName());
                if (i + 1 < parms.length)
                    error.append(", ");
            }
            throw new CompileException("unable to find constructor: " + cls.getName() + "(" + error.toString() + ")", this.expr, this.start);
        }
        for (int i = 0; i < parms.length; i++) {
            // noinspection unchecked
            parms[i] = convert(parms[i], cns.getParameterTypes()[i]);
        }
        AccessorNode ca = new ConstructorAccessor(cns, cStmts);
        if (cnsRes.length > 1) {
            ReflectiveAccessorOptimizer compiledOptimizer = new ReflectiveAccessorOptimizer(pCtx, cnsRes[1].toCharArray(), 0, cnsRes[1].length(), cns.newInstance(parms), ctx, vars);
            compiledOptimizer.ingressType = cns.getDeclaringClass();
            compiledOptimizer.setRootNode(ca);
            compiledOptimizer.compileGetChain();
            ca = compiledOptimizer.getRootNode();
            this.val = compiledOptimizer.getResultOptPass();
        }
        return ca;
    } else {
        Constructor<?> cns = Class.forName(new String(expression), true, Thread.currentThread().getContextClassLoader()).getConstructor(EMPTYCLS);
        AccessorNode ca = new ConstructorAccessor(cns, null);
        if (cnsRes.length > 1) {
            // noinspection NullArgumentToVariableArgMethod
            ReflectiveAccessorOptimizer compiledOptimizer = new ReflectiveAccessorOptimizer(getCurrentThreadParserContext(), cnsRes[1].toCharArray(), 0, cnsRes[1].length(), cns.newInstance(null), ctx, vars);
            compiledOptimizer.setRootNode(ca);
            compiledOptimizer.compileGetChain();
            ca = compiledOptimizer.getRootNode();
            this.val = compiledOptimizer.getResultOptPass();
        }
        return ca;
    }
}
Also used : ExecutableStatement(org.mvel2.compiler.ExecutableStatement) AccessorNode(org.mvel2.compiler.AccessorNode)

Example 7 with AccessorNode

use of org.mule.mvel2.compiler.AccessorNode in project mvel by mikebrock.

the class NullSafe method getValue.

public Object getValue(Object ctx, Object elCtx, VariableResolverFactory variableFactory) {
    if (ctx == null)
        return null;
    if (nextNode == null) {
        final Accessor a = OptimizerFactory.getAccessorCompiler(OptimizerFactory.SAFE_REFLECTIVE).optimizeAccessor(pCtx, expr, start, offset, ctx, elCtx, variableFactory, true, ctx.getClass());
        nextNode = new AccessorNode() {

            public AccessorNode getNextNode() {
                return null;
            }

            public AccessorNode setNextNode(AccessorNode accessorNode) {
                return null;
            }

            public Object getValue(Object ctx, Object elCtx, VariableResolverFactory variableFactory) {
                return a.getValue(ctx, elCtx, variableFactory);
            }

            public Object setValue(Object ctx, Object elCtx, VariableResolverFactory variableFactory, Object value) {
                return a.setValue(ctx, elCtx, variableFactory, value);
            }

            public Class getKnownEgressType() {
                return a.getKnownEgressType();
            }
        };
    }
    // else {
    return nextNode.getValue(ctx, elCtx, variableFactory);
// }
}
Also used : AccessorNode(org.mvel2.compiler.AccessorNode) VariableResolverFactory(org.mvel2.integration.VariableResolverFactory) Accessor(org.mvel2.compiler.Accessor)

Example 8 with AccessorNode

use of org.mule.mvel2.compiler.AccessorNode in project mvel by mvel.

the class ASMAccessorOptimizer method optimizeSetAccessor.

public Accessor optimizeSetAccessor(ParserContext pCtx, char[] property, int start, int offset, Object ctx, Object thisRef, VariableResolverFactory factory, boolean rootThisRef, Object value, Class ingressType) {
    this.expr = property;
    this.start = this.cursor = start;
    this.end = start + offset;
    this.length = start + offset;
    this.first = true;
    this.ingressType = ingressType;
    compiledInputs = new ArrayList<ExecutableStatement>();
    this.pCtx = pCtx;
    this.ctx = ctx;
    this.thisRef = thisRef;
    this.variableFactory = factory;
    char[] root = null;
    PropertyVerifier verifier = new PropertyVerifier(property, this.pCtx = pCtx);
    int split = findLastUnion();
    if (split != -1) {
        root = subset(property, 0, split);
    }
    AccessorNode rootAccessor = null;
    _initJIT2();
    if (root != null) {
        int _length = this.length;
        int _end = this.end;
        char[] _expr = this.expr;
        this.length = end = (this.expr = root).length;
        // run the compiler but don't finish building.
        deferFinish = true;
        noinit = true;
        compileAccessor();
        ctx = this.val;
        this.expr = _expr;
        this.cursor = start + root.length + 1;
        this.length = _length - root.length - 1;
        this.end = this.cursor + this.length;
    } else {
        assert debug("ALOAD 1");
        mv.visitVarInsn(ALOAD, 1);
    }
    try {
        skipWhitespace();
        if (collection) {
            int st = cursor;
            whiteSpaceSkip();
            if (st == end)
                throw new PropertyAccessException("unterminated '['", expr, start, pCtx);
            if (scanTo(']'))
                throw new PropertyAccessException("unterminated '['", expr, start, pCtx);
            String ex = new String(expr, st, cursor - st).trim();
            assert debug("CHECKCAST " + ctx.getClass().getName());
            mv.visitTypeInsn(CHECKCAST, getInternalName(ctx.getClass()));
            if (ctx instanceof Map) {
                if (MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING && hasPropertyHandler(Map.class)) {
                    propHandlerByteCodePut(ex, ctx, Map.class, value);
                } else {
                    // noinspection unchecked
                    ((Map) ctx).put(eval(ex, ctx, variableFactory), convert(value, returnType = verifier.analyze()));
                    writeLiteralOrSubexpression(subCompileExpression(ex.toCharArray(), pCtx));
                    assert debug("ALOAD 4");
                    mv.visitVarInsn(ALOAD, 4);
                    if (value != null && returnType != value.getClass()) {
                        dataConversion(returnType);
                        checkcast(returnType);
                    }
                    assert debug("INVOKEINTERFACE Map.put");
                    mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
                    assert debug("POP");
                    mv.visitInsn(POP);
                    assert debug("ALOAD 4");
                    mv.visitVarInsn(ALOAD, 4);
                }
            } else if (ctx instanceof List) {
                if (MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING && hasPropertyHandler(List.class)) {
                    propHandlerByteCodePut(ex, ctx, List.class, value);
                } else {
                    // noinspection unchecked
                    ((List) ctx).set(eval(ex, ctx, variableFactory, Integer.class), convert(value, returnType = verifier.analyze()));
                    writeLiteralOrSubexpression(subCompileExpression(ex.toCharArray(), pCtx));
                    unwrapPrimitive(int.class);
                    assert debug("ALOAD 4");
                    mv.visitVarInsn(ALOAD, 4);
                    if (value != null && !value.getClass().isAssignableFrom(returnType)) {
                        dataConversion(returnType);
                        checkcast(returnType);
                    }
                    assert debug("INVOKEINTERFACE List.set");
                    mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "set", "(ILjava/lang/Object;)Ljava/lang/Object;");
                    assert debug("ALOAD 4");
                    mv.visitVarInsn(ALOAD, 4);
                }
            } else if (MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING && hasPropertyHandler(ctx.getClass())) {
                propHandlerByteCodePut(ex, ctx, ctx.getClass(), value);
            } else if (ctx.getClass().isArray()) {
                if (MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING && hasPropertyHandler(Array.class)) {
                    propHandlerByteCodePut(ex, ctx, Array.class, value);
                } else {
                    Class type = getBaseComponentType(ctx.getClass());
                    Object idx = eval(ex, ctx, variableFactory);
                    writeLiteralOrSubexpression(subCompileExpression(ex.toCharArray(), pCtx), int.class);
                    if (!(idx instanceof Integer)) {
                        dataConversion(Integer.class);
                        idx = DataConversion.convert(idx, Integer.class);
                        unwrapPrimitive(int.class);
                    }
                    assert debug("ALOAD 4");
                    mv.visitVarInsn(ALOAD, 4);
                    if (type.isPrimitive())
                        unwrapPrimitive(type);
                    else if (!type.equals(value.getClass())) {
                        dataConversion(type);
                    }
                    arrayStore(type);
                    // noinspection unchecked
                    Array.set(ctx, (Integer) idx, convert(value, type));
                    assert debug("ALOAD 4");
                    mv.visitVarInsn(ALOAD, 4);
                }
            } else {
                throw new PropertyAccessException("cannot bind to collection property: " + new String(expr) + ": not a recognized collection type: " + ctx.getClass(), expr, start, pCtx);
            }
            deferFinish = false;
            noinit = false;
            _finishJIT();
            try {
                deferFinish = false;
                return _initializeAccessor();
            } catch (Exception e) {
                throw new CompileException("could not generate accessor", expr, start, e);
            }
        }
        String tk = new String(expr, this.cursor, this.length);
        Member member = getFieldOrWriteAccessor(ctx.getClass(), tk, value == null ? null : ingressType);
        if (GlobalListenerFactory.hasSetListeners()) {
            mv.visitVarInsn(ALOAD, 1);
            mv.visitLdcInsn(tk);
            mv.visitVarInsn(ALOAD, 3);
            mv.visitVarInsn(ALOAD, 4);
            mv.visitMethodInsn(INVOKESTATIC, NAMESPACE + "integration/GlobalListenerFactory", "notifySetListeners", "(Ljava/lang/Object;Ljava/lang/String;L" + NAMESPACE + "integration/VariableResolverFactory;Ljava/lang/Object;)V");
            GlobalListenerFactory.notifySetListeners(ctx, tk, variableFactory, value);
        }
        if (member instanceof Field) {
            checkcast(ctx.getClass());
            Field fld = (Field) member;
            Label jmp = null;
            Label jmp2 = new Label();
            if (fld.getType().isPrimitive()) {
                assert debug("ASTORE 5");
                mv.visitVarInsn(ASTORE, 5);
                assert debug("ALOAD 4");
                mv.visitVarInsn(ALOAD, 4);
                if (value == null)
                    value = PropertyTools.getPrimitiveInitialValue(fld.getType());
                jmp = new Label();
                assert debug("IFNOTNULL jmp");
                mv.visitJumpInsn(IFNONNULL, jmp);
                assert debug("ALOAD 5");
                mv.visitVarInsn(ALOAD, 5);
                assert debug("ICONST_0");
                mv.visitInsn(ICONST_0);
                assert debug("PUTFIELD " + getInternalName(fld.getDeclaringClass()) + "." + tk);
                mv.visitFieldInsn(PUTFIELD, getInternalName(fld.getDeclaringClass()), tk, getDescriptor(fld.getType()));
                assert debug("GOTO jmp2");
                mv.visitJumpInsn(GOTO, jmp2);
                assert debug("jmp:");
                mv.visitLabel(jmp);
                assert debug("ALOAD 5");
                mv.visitVarInsn(ALOAD, 5);
                assert debug("ALOAD 4");
                mv.visitVarInsn(ALOAD, 4);
                unwrapPrimitive(fld.getType());
            } else {
                assert debug("ALOAD 4");
                mv.visitVarInsn(ALOAD, 4);
                checkcast(fld.getType());
            }
            if (jmp == null && value != null && !fld.getType().isAssignableFrom(value.getClass())) {
                if (!canConvert(fld.getType(), value.getClass())) {
                    throw new CompileException("cannot convert type: " + value.getClass() + ": to " + fld.getType(), expr, start);
                }
                dataConversion(fld.getType());
                fld.set(ctx, convert(value, fld.getType()));
            } else {
                fld.set(ctx, value);
            }
            assert debug("PUTFIELD " + getInternalName(fld.getDeclaringClass()) + "." + tk);
            mv.visitFieldInsn(PUTFIELD, getInternalName(fld.getDeclaringClass()), tk, getDescriptor(fld.getType()));
            assert debug("jmp2:");
            mv.visitLabel(jmp2);
            assert debug("ALOAD 4");
            mv.visitVarInsn(ALOAD, 4);
        } else if (member != null) {
            assert debug("CHECKCAST " + getInternalName(ctx.getClass()));
            mv.visitTypeInsn(CHECKCAST, getInternalName(ctx.getClass()));
            Method meth = (Method) member;
            assert debug("ALOAD 4");
            mv.visitVarInsn(ALOAD, 4);
            Class targetType = meth.getParameterTypes()[0];
            Label jmp;
            Label jmp2 = new Label();
            if (value != null && !targetType.isAssignableFrom(value.getClass())) {
                if (!canConvert(targetType, value.getClass())) {
                    throw new CompileException("cannot convert type: " + value.getClass() + ": to " + meth.getParameterTypes()[0], expr, start);
                }
                dataConversion(getWrapperClass(targetType));
                if (targetType.isPrimitive()) {
                    unwrapPrimitive(targetType);
                } else
                    checkcast(targetType);
                meth.invoke(ctx, convert(value, meth.getParameterTypes()[0]));
            } else {
                if (targetType.isPrimitive()) {
                    if (value == null)
                        value = PropertyTools.getPrimitiveInitialValue(targetType);
                    jmp = new Label();
                    assert debug("IFNOTNULL jmp");
                    mv.visitJumpInsn(IFNONNULL, jmp);
                    assert debug("ICONST_0");
                    mv.visitInsn(ICONST_0);
                    assert debug("INVOKEVIRTUAL " + getInternalName(meth.getDeclaringClass()) + "." + meth.getName());
                    mv.visitMethodInsn(INVOKEVIRTUAL, getInternalName(meth.getDeclaringClass()), meth.getName(), getMethodDescriptor(meth));
                    assert debug("GOTO jmp2");
                    mv.visitJumpInsn(GOTO, jmp2);
                    assert debug("jmp:");
                    mv.visitLabel(jmp);
                    assert debug("ALOAD 4");
                    mv.visitVarInsn(ALOAD, 4);
                    unwrapPrimitive(targetType);
                } else {
                    checkcast(targetType);
                }
                meth.invoke(ctx, value);
            }
            assert debug("INVOKEVIRTUAL " + getInternalName(meth.getDeclaringClass()) + "." + meth.getName());
            mv.visitMethodInsn(INVOKEVIRTUAL, getInternalName(meth.getDeclaringClass()), meth.getName(), getMethodDescriptor(meth));
            assert debug("jmp2:");
            mv.visitLabel(jmp2);
            assert debug("ALOAD 4");
            mv.visitVarInsn(ALOAD, 4);
        } else if (ctx instanceof Map) {
            assert debug("CHECKCAST " + getInternalName(ctx.getClass()));
            mv.visitTypeInsn(CHECKCAST, getInternalName(ctx.getClass()));
            assert debug("LDC '" + tk + "'");
            mv.visitLdcInsn(tk);
            assert debug("ALOAD 4");
            mv.visitVarInsn(ALOAD, 4);
            assert debug("INVOKEINTERFACE java/util/Map.put");
            mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
            assert debug("ALOAD 4");
            mv.visitVarInsn(ALOAD, 4);
            // noinspection unchecked
            ((Map) ctx).put(tk, value);
        } else {
            throw new PropertyAccessException("could not access property (" + tk + ") in: " + ingressType.getName(), expr, start, pCtx);
        }
    } catch (InvocationTargetException e) {
        throw new PropertyAccessException("could not access property", expr, start, e, pCtx);
    } catch (IllegalAccessException e) {
        throw new PropertyAccessException("could not access property", expr, start, e, pCtx);
    }
    try {
        deferFinish = false;
        noinit = false;
        _finishJIT();
        return _initializeAccessor();
    } catch (Exception e) {
        throw new CompileException("could not generate accessor", expr, start, e);
    }
}
Also used : ExecutableStatement(org.mvel2.compiler.ExecutableStatement) PropertyVerifier(org.mvel2.compiler.PropertyVerifier) Label(org.mvel2.asm.Label) PropertyAccessException(org.mvel2.PropertyAccessException) Method(java.lang.reflect.Method) CompileException(org.mvel2.CompileException) InvocationTargetException(java.lang.reflect.InvocationTargetException) PropertyAccessException(org.mvel2.PropertyAccessException) IOException(java.io.IOException) InvocationTargetException(java.lang.reflect.InvocationTargetException) Array(java.lang.reflect.Array) ReflectionUtil.toNonPrimitiveArray(org.mvel2.util.ReflectionUtil.toNonPrimitiveArray) Field(java.lang.reflect.Field) AccessorNode(org.mvel2.compiler.AccessorNode) CompileException(org.mvel2.CompileException) List(java.util.List) ArrayList(java.util.ArrayList) Map(java.util.Map) Member(java.lang.reflect.Member)

Example 9 with AccessorNode

use of org.mule.mvel2.compiler.AccessorNode in project drools by kiegroup.

the class ModifyInterceptor method extractMethod.

private Method extractMethod(WithNode.ParmValuePair parmValuePair) {
    Serializable setExpression = parmValuePair.getSetExpression();
    if (setExpression != null) {
        SetterAccessor setterAccessor = (SetterAccessor) ((CompiledAccExpression) setExpression).getAccessor();
        return setterAccessor.getMethod();
    } else {
        ExecutableAccessor accessor = (ExecutableAccessor) parmValuePair.getStatement();
        AccessorNode accessorNode = (AccessorNode) accessor.getNode().getAccessor();
        MethodAccessor methodAccessor = (MethodAccessor) accessorNode.getNextNode();
        return methodAccessor.getMethod();
    }
}
Also used : SetterAccessor(org.mvel2.optimizers.impl.refl.nodes.SetterAccessor) Serializable(java.io.Serializable) AccessorNode(org.mvel2.compiler.AccessorNode) MethodAccessor(org.mvel2.optimizers.impl.refl.nodes.MethodAccessor) ExecutableAccessor(org.mvel2.compiler.ExecutableAccessor)

Example 10 with AccessorNode

use of org.mule.mvel2.compiler.AccessorNode in project mule by mulesoft.

the class AbstractVariableExpressionDataTypeResolver method getDataType.

@Override
protected DataType getDataType(PrivilegedEvent event, ASTNode node) {
    final Accessor accessor = node.getAccessor();
    if (accessor instanceof VariableAccessor) {
        VariableAccessor variableAccessor = (VariableAccessor) accessor;
        if (variableAccessor.getProperty().equals(propertyName)) {
            final AccessorNode nextNode = variableAccessor.getNextNode();
            String propertyName = null;
            if (nextNode instanceof MapAccessorNest) {
                final MapAccessorNest mapAccesorNest = (MapAccessorNest) nextNode;
                if (mapAccesorNest.getProperty().isLiteralOnly()) {
                    propertyName = (String) ((ExecutableLiteral) mapAccesorNest.getProperty()).getLiteral();
                }
            } else if (nextNode instanceof MapAccessor) {
                propertyName = (String) ((MapAccessor) nextNode).getProperty();
            }
            if (propertyName != null) {
                return getVariableDataType(event, propertyName);
            }
        }
    }
    return null;
}
Also used : AccessorNode(org.mule.mvel2.compiler.AccessorNode) VariableAccessor(org.mule.mvel2.optimizers.impl.refl.nodes.VariableAccessor) ExecutableLiteral(org.mule.mvel2.compiler.ExecutableLiteral) MapAccessor(org.mule.mvel2.optimizers.impl.refl.nodes.MapAccessor) MapAccessorNest(org.mule.mvel2.optimizers.impl.refl.nodes.MapAccessorNest) MapAccessor(org.mule.mvel2.optimizers.impl.refl.nodes.MapAccessor) Accessor(org.mule.mvel2.compiler.Accessor) VariableAccessor(org.mule.mvel2.optimizers.impl.refl.nodes.VariableAccessor)

Aggregations

AccessorNode (org.mvel2.compiler.AccessorNode)8 ExecutableStatement (org.mvel2.compiler.ExecutableStatement)4 Accessor (org.mvel2.compiler.Accessor)3 AccessorNode (org.mule.mvel2.compiler.AccessorNode)2 ExecutableLiteral (org.mule.mvel2.compiler.ExecutableLiteral)2 MapAccessor (org.mule.mvel2.optimizers.impl.refl.nodes.MapAccessor)2 MapAccessorNest (org.mule.mvel2.optimizers.impl.refl.nodes.MapAccessorNest)2 VariableAccessor (org.mule.mvel2.optimizers.impl.refl.nodes.VariableAccessor)2 CompileException (org.mvel2.CompileException)2 ExecutableAccessor (org.mvel2.compiler.ExecutableAccessor)2 VariableResolverFactory (org.mvel2.integration.VariableResolverFactory)2 DynamicGetAccessor (org.mvel2.optimizers.dynamic.DynamicGetAccessor)2 ConstructorAccessor (org.mvel2.optimizers.impl.refl.nodes.ConstructorAccessor)2 IndexedVariableAccessor (org.mvel2.optimizers.impl.refl.nodes.IndexedVariableAccessor)2 MethodAccessor (org.mvel2.optimizers.impl.refl.nodes.MethodAccessor)2 StaticReferenceAccessor (org.mvel2.optimizers.impl.refl.nodes.StaticReferenceAccessor)2 VariableAccessor (org.mvel2.optimizers.impl.refl.nodes.VariableAccessor)2 IOException (java.io.IOException)1 Serializable (java.io.Serializable)1 Array (java.lang.reflect.Array)1