Search in sources :

Example 6 with ArrayLength

use of org.mvel2.optimizers.impl.refl.nodes.ArrayLength in project mvel by mikebrock.

the class ASMAccessorOptimizer method getBeanProperty.

private Object getBeanProperty(Object ctx, String property) throws IllegalAccessException, InvocationTargetException {
    assert debug("\n  **  ENTER -> {bean: " + property + "; ctx=" + ctx + "}");
    if ((pCtx == null ? currType : pCtx.getVarOrInputTypeOrNull(property)) == Object.class && !pCtx.isStrongTyping()) {
        currType = null;
    }
    if (returnType != null && returnType.isPrimitive()) {
        // noinspection unchecked
        wrapPrimitive(returnType);
    }
    boolean classRef = false;
    Class<?> cls;
    if (ctx instanceof Class) {
        if (MVEL.COMPILER_OPT_SUPPORT_JAVA_STYLE_CLASS_LITERALS && "class".equals(property)) {
            ldcClassConstant((Class<?>) ctx);
            return ctx;
        }
        cls = (Class<?>) ctx;
        classRef = true;
    } else if (ctx != null) {
        cls = ctx.getClass();
    } else {
        cls = null;
    }
    if (hasPropertyHandler(cls)) {
        PropertyHandler prop = getPropertyHandler(cls);
        if (prop instanceof ProducesBytecode) {
            ((ProducesBytecode) prop).produceBytecodeGet(mv, property, variableFactory);
            return prop.getProperty(property, ctx, variableFactory);
        } else {
            throw new RuntimeException("unable to compileShared: custom accessor does not support producing bytecode: " + prop.getClass().getName());
        }
    }
    Member member = cls != null ? getFieldOrAccessor(cls, property) : null;
    if (member != null && classRef && (member.getModifiers() & Modifier.STATIC) == 0) {
        member = null;
    }
    if (member != null && hasGetListeners()) {
        mv.visitVarInsn(ALOAD, 1);
        mv.visitLdcInsn(member.getName());
        mv.visitVarInsn(ALOAD, 3);
        mv.visitMethodInsn(INVOKESTATIC, NAMESPACE + "integration/GlobalListenerFactory", "notifyGetListeners", "(Ljava/lang/Object;Ljava/lang/String;L" + NAMESPACE + "integration/VariableResolverFactory;)V");
        notifyGetListeners(ctx, member.getName(), variableFactory);
    }
    if (first) {
        if ("this".equals(property)) {
            assert debug("ALOAD 2");
            mv.visitVarInsn(ALOAD, 2);
            return thisRef;
        } else if (variableFactory != null && variableFactory.isResolveable(property)) {
            if (variableFactory.isIndexedFactory() && variableFactory.isTarget(property)) {
                int idx;
                try {
                    loadVariableByIndex(idx = variableFactory.variableIndexOf(property));
                } catch (Exception e) {
                    throw new OptimizationFailure(property);
                }
                return variableFactory.getIndexedVariableResolver(idx).getValue();
            } else {
                try {
                    loadVariableByName(property);
                } catch (Exception e) {
                    throw new OptimizationFailure("critical error in JIT", e);
                }
                return variableFactory.getVariableResolver(property).getValue();
            }
        } else {
            assert debug("ALOAD 1");
            mv.visitVarInsn(ALOAD, 1);
        }
    }
    if (member instanceof Field) {
        Object o = ((Field) member).get(ctx);
        if (((member.getModifiers() & STATIC) != 0)) {
            // Check if the static field reference is a constant and a primitive.
            if ((member.getModifiers() & FINAL) != 0 && (o instanceof String || ((Field) member).getType().isPrimitive())) {
                o = ((Field) member).get(null);
                assert debug("LDC " + valueOf(o));
                mv.visitLdcInsn(o);
                wrapPrimitive(o.getClass());
                if (hasNullPropertyHandler()) {
                    if (o == null) {
                        o = getNullPropertyHandler().getProperty(member.getName(), ctx, variableFactory);
                    }
                    writeOutNullHandler(member, 0);
                }
                return o;
            } else {
                assert debug("GETSTATIC " + getDescriptor(member.getDeclaringClass()) + "." + member.getName() + "::" + getDescriptor(((Field) member).getType()));
                mv.visitFieldInsn(GETSTATIC, getInternalName(member.getDeclaringClass()), member.getName(), getDescriptor(returnType = ((Field) member).getType()));
            }
        } else {
            assert debug("CHECKCAST " + getInternalName(cls));
            mv.visitTypeInsn(CHECKCAST, getInternalName(cls));
            assert debug("GETFIELD " + property + ":" + getDescriptor(((Field) member).getType()));
            mv.visitFieldInsn(GETFIELD, getInternalName(cls), property, getDescriptor(returnType = ((Field) member).getType()));
        }
        returnType = ((Field) member).getType();
        if (hasNullPropertyHandler()) {
            if (o == null) {
                o = getNullPropertyHandler().getProperty(member.getName(), ctx, variableFactory);
            }
            writeOutNullHandler(member, 0);
        }
        return o;
    } else if (member != null) {
        Object o;
        if (first) {
            assert debug("ALOAD 1 (B)");
            mv.visitVarInsn(ALOAD, 1);
        }
        try {
            o = ((Method) member).invoke(ctx, EMPTYARG);
            if (returnType != member.getDeclaringClass()) {
                assert debug("CHECKCAST " + getInternalName(member.getDeclaringClass()));
                mv.visitTypeInsn(CHECKCAST, getInternalName(member.getDeclaringClass()));
            }
            returnType = ((Method) member).getReturnType();
            assert debug("INVOKEVIRTUAL " + member.getName() + ":" + returnType);
            mv.visitMethodInsn(INVOKEVIRTUAL, getInternalName(member.getDeclaringClass()), member.getName(), getMethodDescriptor((Method) member));
        } catch (IllegalAccessException e) {
            Method iFaceMeth = determineActualTargetMethod((Method) member);
            if (iFaceMeth == null)
                throw new PropertyAccessException("could not access field: " + cls.getName() + "." + property, expr, st, e);
            assert debug("CHECKCAST " + getInternalName(iFaceMeth.getDeclaringClass()));
            mv.visitTypeInsn(CHECKCAST, getInternalName(iFaceMeth.getDeclaringClass()));
            returnType = iFaceMeth.getReturnType();
            assert debug("INVOKEINTERFACE " + member.getName() + ":" + returnType);
            mv.visitMethodInsn(INVOKEINTERFACE, getInternalName(iFaceMeth.getDeclaringClass()), member.getName(), getMethodDescriptor((Method) member));
            o = iFaceMeth.invoke(ctx, EMPTYARG);
        } catch (IllegalArgumentException e) {
            if (member.getDeclaringClass().equals(ctx)) {
                try {
                    Class c = Class.forName(member.getDeclaringClass().getName() + "$" + property);
                    throw new CompileException("name collision between innerclass: " + c.getCanonicalName() + "; and bean accessor: " + property + " (" + member.toString() + ")", expr, tkStart);
                } catch (ClassNotFoundException e2) {
                // fallthru
                }
            }
            throw e;
        }
        if (hasNullPropertyHandler()) {
            if (o == null)
                o = getNullPropertyHandler().getProperty(member.getName(), ctx, variableFactory);
            writeOutNullHandler(member, 0);
        }
        return o;
    } else if (ctx instanceof Map && (((Map) ctx).containsKey(property) || nullSafe)) {
        assert debug("CHECKCAST java/util/Map");
        mv.visitTypeInsn(CHECKCAST, "java/util/Map");
        assert debug("LDC: \"" + property + "\"");
        mv.visitLdcInsn(property);
        assert debug("INVOKEINTERFACE: get");
        mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
        return ((Map) ctx).get(property);
    } else if (first && "this".equals(property)) {
        assert debug("ALOAD 2");
        // load the thisRef value.
        mv.visitVarInsn(ALOAD, 2);
        return this.thisRef;
    } else if ("length".equals(property) && ctx.getClass().isArray()) {
        anyArrayCheck(ctx.getClass());
        assert debug("ARRAYLENGTH");
        mv.visitInsn(ARRAYLENGTH);
        wrapPrimitive(int.class);
        return getLength(ctx);
    } else if (LITERALS.containsKey(property)) {
        Object lit = LITERALS.get(property);
        if (lit instanceof Class) {
            ldcClassConstant((Class) lit);
        }
        return lit;
    } else {
        Object ts = tryStaticAccess();
        if (ts != null) {
            if (ts instanceof Class) {
                ldcClassConstant((Class) ts);
                return ts;
            } else if (ts instanceof Method) {
                writeFunctionPointerStub(((Method) ts).getDeclaringClass(), (Method) ts);
                return ts;
            } else {
                Field f = (Field) ts;
                if ((f.getModifiers() & FINAL) != 0) {
                    Object finalVal = f.get(null);
                    assert debug("LDC " + valueOf(finalVal));
                    mv.visitLdcInsn(finalVal);
                    wrapPrimitive(finalVal.getClass());
                    return finalVal;
                } else {
                    assert debug("GETSTATIC " + getInternalName(f.getDeclaringClass()) + "." + ((Field) ts).getName() + "::" + getDescriptor(f.getType()));
                    mv.visitFieldInsn(GETSTATIC, getInternalName(f.getDeclaringClass()), f.getName(), getDescriptor(returnType = f.getType()));
                    return f.get(null);
                }
            }
        } else if (ctx instanceof Class) {
            /**
             * This is our ugly support for function pointers.  This works but needs to be re-thought out at some
             * point.
             */
            Class c = (Class) ctx;
            for (Method m : c.getMethods()) {
                if (property.equals(m.getName())) {
                    if (MVEL.COMPILER_OPT_ALLOW_NAKED_METH_CALL) {
                        assert debug("POP");
                        mv.visitInsn(POP);
                        assert debug("INVOKESTATIC " + m.getName());
                        mv.visitMethodInsn(INVOKESTATIC, getInternalName(m.getDeclaringClass()), m.getName(), getMethodDescriptor(m));
                        returnType = m.getReturnType();
                        return m.invoke(null, EMPTY_OBJ_ARR);
                    } else {
                        writeFunctionPointerStub(c, m);
                        return m;
                    }
                }
            }
            try {
                Class subClass = findClass(variableFactory, c.getName() + "$" + property, pCtx);
                ldcClassConstant(subClass);
                return subClass;
            } catch (ClassNotFoundException cnfe) {
            // fall through.
            }
        } else if (MVEL.COMPILER_OPT_ALLOW_NAKED_METH_CALL) {
            return getMethod(ctx, property);
        }
        if (ctx == null) {
            throw new PropertyAccessException("unresolvable property or identifier: " + property, expr, st);
        } else {
            throw new PropertyAccessException("could not access: " + property + "; in class: " + ctx.getClass().getName(), expr, st);
        }
    }
}
Also used : IOException(java.io.IOException) PropertyHandler(org.mvel2.integration.PropertyHandler) Map(java.util.Map)

Example 7 with ArrayLength

use of org.mvel2.optimizers.impl.refl.nodes.ArrayLength in project drools by kiegroup.

the class ConditionAnalyzer method analyzeAccessorInvocation.

private Invocation analyzeAccessorInvocation(AccessorNode accessorNode, ASTNode containingNode, Invocation formerInvocation, Class<?> variableType) {
    if (accessorNode instanceof GetterAccessor) {
        return new MethodInvocation(((GetterAccessor) accessorNode).getMethod(), variableType == null ? conditionClass : variableType.getName());
    }
    if (accessorNode instanceof MethodAccessor) {
        MethodAccessor methodAccessor = (MethodAccessor) accessorNode;
        Method method = methodAccessor.getMethod();
        MethodInvocation invocation = new MethodInvocation(method);
        boolean isVarArgs = method.isVarArgs();
        readInvocationParams(invocation, methodAccessor.getParms(), methodAccessor.getParameterTypes(), isVarArgs);
        return invocation;
    }
    if (accessorNode instanceof ConstructorAccessor) {
        ConstructorAccessor constructorAccessor = (ConstructorAccessor) accessorNode;
        Constructor constructor = constructorAccessor.getConstructor();
        ConstructorInvocation invocation = new ConstructorInvocation(constructor);
        readInvocationParams(invocation, constructorAccessor.getParameters(), constructorAccessor.getParameterTypes(), constructor.isVarArgs());
        return invocation;
    }
    if (accessorNode instanceof ArrayAccessor) {
        ArrayAccessor arrayAccessor = (ArrayAccessor) accessorNode;
        return new ArrayAccessInvocation(formerInvocation != null ? formerInvocation.getReturnType() : Object[].class, new FixedExpression(int.class, arrayAccessor.getIndex()));
    }
    if (accessorNode instanceof ArrayAccessorNest) {
        ArrayAccessorNest arrayAccessorNest = (ArrayAccessorNest) accessorNode;
        ExecutableAccessor index = (ExecutableAccessor) arrayAccessorNest.getIndex();
        return new ArrayAccessInvocation(formerInvocation != null ? formerInvocation.getReturnType() : Object[].class, analyzeNode(index.getNode()));
    }
    if (accessorNode instanceof ArrayLength) {
        return new ArrayLengthInvocation();
    }
    if (accessorNode instanceof ListAccessor) {
        Class<?> listType = getListType(formerInvocation);
        ListAccessor listAccessor = (ListAccessor) accessorNode;
        return new ListAccessInvocation(listType, new FixedExpression(int.class, listAccessor.getIndex()));
    }
    if (accessorNode instanceof ListAccessorNest) {
        Class<?> listType = getListType(formerInvocation);
        ListAccessorNest listAccessorNest = (ListAccessorNest) accessorNode;
        ExecutableAccessor index = (ExecutableAccessor) listAccessorNest.getIndex();
        return new ListAccessInvocation(listType, analyzeNode(index.getNode()));
    }
    if (accessorNode instanceof MapAccessor) {
        MapAccessor mapAccessor = (MapAccessor) accessorNode;
        return new MapAccessInvocation(Object.class, Object.class, new FixedExpression(Object.class, mapAccessor.getProperty()));
    }
    if (accessorNode instanceof MapAccessorNest) {
        Class<?> keyType = Object.class;
        Class<?> valueType = Object.class;
        Type[] generics = getGenerics(formerInvocation);
        if (generics != null && generics.length == 2 && generics[0] instanceof Class) {
            keyType = (Class<?>) generics[0];
            if (generics[1] instanceof Class)
                valueType = (Class<?>) generics[1];
        }
        MapAccessorNest mapAccessor = (MapAccessorNest) accessorNode;
        ExecutableStatement statement = mapAccessor.getProperty();
        if (statement instanceof ExecutableLiteral) {
            return new MapAccessInvocation(keyType, valueType, new FixedExpression(keyType, ((ExecutableLiteral) statement).getLiteral()));
        } else {
            return new MapAccessInvocation(keyType, valueType, analyzeNode(((ExecutableAccessor) statement).getNode()));
        }
    }
    if (accessorNode instanceof FieldAccessor) {
        return new FieldAccessInvocation(((FieldAccessor) accessorNode).getField());
    }
    if (accessorNode instanceof StaticVarAccessor) {
        Field field = ((StaticVarAccessor) accessorNode).getField();
        return new FieldAccessInvocation(field);
    }
    if (accessorNode instanceof ThisValueAccessor) {
        return new ThisInvocation(accessorNode.getNextNode() == null ? containingNode.getEgressType() : Object.class);
    }
    throw new RuntimeException("Unknown AccessorNode type: " + accessorNode.getClass().getName());
}
Also used : ArrayAccessorNest(org.mvel2.optimizers.impl.refl.nodes.ArrayAccessorNest) ExecutableAccessor(org.mvel2.compiler.ExecutableAccessor) FieldAccessor(org.mvel2.optimizers.impl.refl.nodes.FieldAccessor) ListAccessor(org.mvel2.optimizers.impl.refl.nodes.ListAccessor) Field(java.lang.reflect.Field) ThisValueAccessor(org.mvel2.optimizers.impl.refl.nodes.ThisValueAccessor) ExecutableLiteral(org.mvel2.compiler.ExecutableLiteral) MapAccessor(org.mvel2.optimizers.impl.refl.nodes.MapAccessor) ExecutableStatement(org.mvel2.compiler.ExecutableStatement) GetterAccessor(org.mvel2.optimizers.impl.refl.nodes.GetterAccessor) MethodAccessor(org.mvel2.optimizers.impl.refl.nodes.MethodAccessor) Constructor(java.lang.reflect.Constructor) ArrayLength(org.mvel2.optimizers.impl.refl.nodes.ArrayLength) StaticVarAccessor(org.mvel2.optimizers.impl.refl.nodes.StaticVarAccessor) Method(java.lang.reflect.Method) MapAccessorNest(org.mvel2.optimizers.impl.refl.nodes.MapAccessorNest) ArrayAccessor(org.mvel2.optimizers.impl.refl.nodes.ArrayAccessor) ClassUtils.convertToPrimitiveType(org.drools.core.util.ClassUtils.convertToPrimitiveType) Type(java.lang.reflect.Type) ParameterizedType(java.lang.reflect.ParameterizedType) ListAccessorNest(org.mvel2.optimizers.impl.refl.nodes.ListAccessorNest) ConstructorAccessor(org.mvel2.optimizers.impl.refl.nodes.ConstructorAccessor)

Example 8 with ArrayLength

use of org.mvel2.optimizers.impl.refl.nodes.ArrayLength in project mvel by mvel.

the class ReflectiveAccessorOptimizer method getMethod.

private Object getMethod(Object ctx, String name, Object[] args, Class[] argTypes, ExecutableStatement[] es) throws Exception {
    if (first && variableFactory != null && variableFactory.isResolveable(name)) {
        Object ptr = variableFactory.getVariableResolver(name).getValue();
        if (ptr instanceof Method) {
            ctx = ((Method) ptr).getDeclaringClass();
            name = ((Method) ptr).getName();
        } else if (ptr instanceof MethodStub) {
            ctx = ((MethodStub) ptr).getClassReference();
            name = ((MethodStub) ptr).getMethodName();
        } else if (ptr instanceof FunctionInstance) {
            FunctionInstance func = (FunctionInstance) ptr;
            if (!name.equals(func.getFunction().getName())) {
                getBeanProperty(ctx, name);
                addAccessorNode(new DynamicFunctionAccessor(es));
            } else {
                addAccessorNode(new FunctionAccessor(func, es));
            }
            return func.call(ctx, thisRef, variableFactory, args);
        } else {
            throw new OptimizationFailure("attempt to optimize a method call for a reference that does not point to a method: " + name + " (reference is type: " + (ctx != null ? ctx.getClass().getName() : null) + ")");
        }
        first = false;
    }
    if (ctx == null && currType == null) {
        throw new PropertyAccessException("null pointer or function not found: " + name, this.expr, this.start, pCtx);
    }
    boolean classTarget = false;
    Class<?> cls = currType != null ? currType : ((classTarget = ctx instanceof Class) ? (Class<?>) ctx : ctx.getClass());
    currType = null;
    Method m;
    Class[] parameterTypes = null;
    /**
     * Try to find an instance method from the class target.
     */
    if ((m = getBestCandidate(argTypes, name, cls, cls.getMethods(), false, classTarget)) != null) {
        parameterTypes = m.getParameterTypes();
    }
    if (m == null && classTarget) {
        /**
         * If we didn't find anything, maybe we're looking for the actual java.lang.Class methods.
         */
        if ((m = getBestCandidate(argTypes, name, cls, Class.class.getMethods(), false)) != null) {
            parameterTypes = m.getParameterTypes();
        }
    }
    // If we didn't find anything and the declared class is different from the actual one try also with the actual one
    if (m == null && ctx != null && cls != ctx.getClass() && !(ctx instanceof Class)) {
        cls = ctx.getClass();
        if ((m = getBestCandidate(argTypes, name, cls, cls.getMethods(), false, classTarget)) != null) {
            parameterTypes = m.getParameterTypes();
        }
    }
    if (m == null) {
        StringAppender errorBuild = new StringAppender();
        if ("size".equals(name) && args.length == 0 && cls.isArray()) {
            addAccessorNode(new ArrayLength());
            return getLength(ctx);
        }
        for (int i = 0; i < args.length; i++) {
            errorBuild.append(args[i] != null ? args[i].getClass().getName() : null);
            if (i < args.length - 1)
                errorBuild.append(", ");
        }
        throw new PropertyAccessException("unable to resolve method: " + cls.getName() + "." + name + "(" + errorBuild.toString() + ") [arglength=" + args.length + "]", this.expr, this.st, pCtx);
    }
    if (es != null) {
        ExecutableStatement cExpr;
        for (int i = 0; i < es.length; i++) {
            cExpr = es[i];
            if (cExpr.getKnownIngressType() == null) {
                cExpr.setKnownIngressType(paramTypeVarArgsSafe(parameterTypes, i, m.isVarArgs()));
                cExpr.computeTypeConversionRule();
            }
            if (!cExpr.isConvertableIngressEgress()) {
                args[i] = convert(args[i], paramTypeVarArgsSafe(parameterTypes, i, m.isVarArgs()));
            }
        }
    } else {
        /**
         * Coerce any types if required.
         */
        for (int i = 0; i < args.length; i++) args[i] = convert(args[i], paramTypeVarArgsSafe(parameterTypes, i, m.isVarArgs()));
    }
    Method method = getWidenedTarget(cls, m);
    Object o = ctx != null ? method.invoke(ctx, normalizeArgsForVarArgs(parameterTypes, args, m.isVarArgs())) : null;
    if (hasNullMethodHandler()) {
        addAccessorNode(new MethodAccessorNH(method, (ExecutableStatement[]) es, getNullMethodHandler()));
        if (o == null)
            o = getNullMethodHandler().getProperty(m.getName(), ctx, variableFactory);
    } else {
        addAccessorNode(new MethodAccessor(method, (ExecutableStatement[]) es));
    }
    /**
     * return the response.
     */
    currType = toNonPrimitiveType(method.getReturnType());
    return o;
}
Also used : ExecutableStatement(org.mvel2.compiler.ExecutableStatement) MethodAccessor(org.mvel2.optimizers.impl.refl.nodes.MethodAccessor) DynamicFunctionAccessor(org.mvel2.optimizers.impl.refl.nodes.DynamicFunctionAccessor) DynamicFunctionAccessor(org.mvel2.optimizers.impl.refl.nodes.DynamicFunctionAccessor) FunctionAccessor(org.mvel2.optimizers.impl.refl.nodes.FunctionAccessor) OptimizationFailure(org.mvel2.OptimizationFailure) PropertyAccessException(org.mvel2.PropertyAccessException) ArrayLength(org.mvel2.optimizers.impl.refl.nodes.ArrayLength) Method(java.lang.reflect.Method) MethodAccessorNH(org.mvel2.optimizers.impl.refl.nodes.MethodAccessorNH) FunctionInstance(org.mvel2.ast.FunctionInstance) MethodStub(org.mvel2.util.MethodStub) StringAppender(org.mvel2.util.StringAppender)

Example 9 with ArrayLength

use of org.mvel2.optimizers.impl.refl.nodes.ArrayLength in project mvel by mvel.

the class ReflectiveAccessorOptimizer method getBeanProperty.

private Object getBeanProperty(Object ctx, String property) throws Exception {
    if ((pCtx == null ? currType : pCtx.getVarOrInputTypeOrNull(property)) == Object.class && !pCtx.isStrongTyping()) {
        currType = null;
    }
    if (first) {
        if ("this".equals(property)) {
            addAccessorNode(new ThisValueAccessor());
            return this.thisRef;
        } else if (variableFactory != null && variableFactory.isResolveable(property)) {
            if (variableFactory.isIndexedFactory() && variableFactory.isTarget(property)) {
                int idx;
                addAccessorNode(new IndexedVariableAccessor(idx = variableFactory.variableIndexOf(property)));
                VariableResolver vr = variableFactory.getIndexedVariableResolver(idx);
                if (vr == null) {
                    variableFactory.setIndexedVariableResolver(idx, variableFactory.getVariableResolver(property));
                }
                return variableFactory.getIndexedVariableResolver(idx).getValue();
            } else {
                addAccessorNode(new VariableAccessor(property));
                return variableFactory.getVariableResolver(property).getValue();
            }
        }
    }
    boolean classRef = false;
    Class<?> cls;
    if (ctx instanceof Class) {
        if (MVEL.COMPILER_OPT_SUPPORT_JAVA_STYLE_CLASS_LITERALS && "class".equals(property)) {
            return ctx;
        }
        cls = (Class<?>) ctx;
        classRef = true;
    } else if (ctx != null) {
        cls = ctx.getClass();
    } else {
        cls = currType;
    }
    if (hasPropertyHandler(cls)) {
        PropertyHandlerAccessor acc = new PropertyHandlerAccessor(property, cls, getPropertyHandler(cls));
        addAccessorNode(acc);
        return acc.getValue(ctx, thisRef, variableFactory);
    }
    Member member = cls != null ? getFieldOrAccessor(cls, property) : null;
    if (member != null && classRef && (member.getModifiers() & Modifier.STATIC) == 0) {
        member = null;
    }
    Object o;
    if (member instanceof Method) {
        try {
            o = ctx != null ? ((Method) member).invoke(ctx, EMPTYARG) : null;
            if (hasNullPropertyHandler()) {
                addAccessorNode(new GetterAccessorNH((Method) member, getNullPropertyHandler()));
                if (o == null)
                    o = getNullPropertyHandler().getProperty(member.getName(), ctx, variableFactory);
            } else {
                addAccessorNode(new GetterAccessor((Method) member));
            }
        } catch (IllegalAccessException e) {
            Method iFaceMeth = determineActualTargetMethod((Method) member);
            if (iFaceMeth == null)
                throw new PropertyAccessException("could not access field: " + cls.getName() + "." + property, this.expr, this.start, pCtx);
            o = iFaceMeth.invoke(ctx, EMPTYARG);
            if (hasNullPropertyHandler()) {
                addAccessorNode(new GetterAccessorNH((Method) member, getNullMethodHandler()));
                if (o == null)
                    o = getNullMethodHandler().getProperty(member.getName(), ctx, variableFactory);
            } else {
                addAccessorNode(new GetterAccessor(iFaceMeth));
            }
        } catch (IllegalArgumentException e) {
            if (member.getDeclaringClass().equals(ctx)) {
                try {
                    Class c = Class.forName(member.getDeclaringClass().getName() + "$" + property);
                    throw new CompileException("name collision between innerclass: " + c.getCanonicalName() + "; and bean accessor: " + property + " (" + member.toString() + ")", expr, tkStart);
                } catch (ClassNotFoundException e2) {
                // fallthru
                }
            }
            throw e;
        }
        currType = toNonPrimitiveType(((Method) member).getReturnType());
        return o;
    } else if (member != null) {
        Field f = (Field) member;
        if ((f.getModifiers() & Modifier.STATIC) != 0) {
            o = f.get(null);
            if (hasNullPropertyHandler()) {
                addAccessorNode(new StaticVarAccessorNH((Field) member, getNullMethodHandler()));
                if (o == null)
                    o = getNullMethodHandler().getProperty(member.getName(), ctx, variableFactory);
            } else {
                addAccessorNode(new StaticVarAccessor((Field) member));
            }
        } else {
            o = ctx != null ? f.get(ctx) : null;
            if (hasNullPropertyHandler()) {
                addAccessorNode(new FieldAccessorNH((Field) member, getNullMethodHandler()));
                if (o == null)
                    o = getNullMethodHandler().getProperty(member.getName(), ctx, variableFactory);
            } else {
                addAccessorNode(new FieldAccessor((Field) member));
            }
        }
        currType = toNonPrimitiveType(f.getType());
        return o;
    } else if (ctx instanceof Map && (((Map) ctx).containsKey(property) || nullSafe)) {
        addAccessorNode(new MapAccessor(property));
        return ((Map) ctx).get(property);
    } else if (ctx != null && "length".equals(property) && ctx.getClass().isArray()) {
        addAccessorNode(new ArrayLength());
        return getLength(ctx);
    } else if (LITERALS.containsKey(property)) {
        addAccessorNode(new StaticReferenceAccessor(ctx = LITERALS.get(property)));
        return ctx;
    } else {
        Object tryStaticMethodRef = tryStaticAccess();
        staticAccess = true;
        if (tryStaticMethodRef != null) {
            if (tryStaticMethodRef instanceof Class) {
                addAccessorNode(new StaticReferenceAccessor(tryStaticMethodRef));
                return tryStaticMethodRef;
            } else if (tryStaticMethodRef instanceof Field) {
                addAccessorNode(new StaticVarAccessor((Field) tryStaticMethodRef));
                return ((Field) tryStaticMethodRef).get(null);
            } else {
                addAccessorNode(new StaticReferenceAccessor(tryStaticMethodRef));
                return tryStaticMethodRef;
            }
        } else if (ctx instanceof Class) {
            Class c = (Class) ctx;
            for (Method m : c.getMethods()) {
                if (property.equals(m.getName())) {
                    if (pCtx != null && pCtx.getParserConfiguration() != null ? pCtx.getParserConfiguration().isAllowNakedMethCall() : MVEL.COMPILER_OPT_ALLOW_NAKED_METH_CALL) {
                        o = m.invoke(null, EMPTY_OBJ_ARR);
                        if (hasNullMethodHandler()) {
                            addAccessorNode(new MethodAccessorNH(m, new ExecutableStatement[0], getNullMethodHandler()));
                            if (o == null)
                                o = getNullMethodHandler().getProperty(m.getName(), ctx, variableFactory);
                        } else {
                            addAccessorNode(new MethodAccessor(m, new ExecutableStatement[0]));
                        }
                        return o;
                    } else {
                        addAccessorNode(new StaticReferenceAccessor(m));
                        return m;
                    }
                }
            }
            try {
                Class subClass = findClass(variableFactory, c.getName() + "$" + property, pCtx);
                addAccessorNode(new StaticReferenceAccessor(subClass));
                return subClass;
            } catch (ClassNotFoundException cnfe) {
            // fall through.
            }
        } else if (pCtx != null && pCtx.getParserConfiguration() != null ? pCtx.getParserConfiguration().isAllowNakedMethCall() : MVEL.COMPILER_OPT_ALLOW_NAKED_METH_CALL) {
            return getMethod(ctx, property);
        }
        if (ctx == null) {
            throw new PropertyAccessException("unresolvable property or identifier: " + property, expr, start, pCtx);
        } else {
            throw new PropertyAccessException("could not access: " + property + "; in class: " + ctx.getClass().getName(), expr, start, pCtx);
        }
    }
}
Also used : FieldAccessorNH(org.mvel2.optimizers.impl.refl.nodes.FieldAccessorNH) FieldAccessor(org.mvel2.optimizers.impl.refl.nodes.FieldAccessor) DynamicFieldAccessor(org.mvel2.optimizers.impl.refl.nodes.DynamicFieldAccessor) Field(java.lang.reflect.Field) GetterAccessorNH(org.mvel2.optimizers.impl.refl.nodes.GetterAccessorNH) ThisValueAccessor(org.mvel2.optimizers.impl.refl.nodes.ThisValueAccessor) StaticVarAccessorNH(org.mvel2.optimizers.impl.refl.nodes.StaticVarAccessorNH) CompileException(org.mvel2.CompileException) MapAccessor(org.mvel2.optimizers.impl.refl.nodes.MapAccessor) Member(java.lang.reflect.Member) GetterAccessor(org.mvel2.optimizers.impl.refl.nodes.GetterAccessor) IndexedVariableAccessor(org.mvel2.optimizers.impl.refl.nodes.IndexedVariableAccessor) VariableAccessor(org.mvel2.optimizers.impl.refl.nodes.VariableAccessor) MethodAccessor(org.mvel2.optimizers.impl.refl.nodes.MethodAccessor) PropertyAccessException(org.mvel2.PropertyAccessException) ArrayLength(org.mvel2.optimizers.impl.refl.nodes.ArrayLength) StaticVarAccessor(org.mvel2.optimizers.impl.refl.nodes.StaticVarAccessor) Method(java.lang.reflect.Method) PropertyHandlerAccessor(org.mvel2.optimizers.impl.refl.nodes.PropertyHandlerAccessor) StaticReferenceAccessor(org.mvel2.optimizers.impl.refl.nodes.StaticReferenceAccessor) MethodAccessorNH(org.mvel2.optimizers.impl.refl.nodes.MethodAccessorNH) IndexedVariableAccessor(org.mvel2.optimizers.impl.refl.nodes.IndexedVariableAccessor) VariableResolver(org.mvel2.integration.VariableResolver) Map(java.util.Map)

Example 10 with ArrayLength

use of org.mvel2.optimizers.impl.refl.nodes.ArrayLength in project mvel by mvel.

the class ASMAccessorOptimizer method writeFunctionPointerStub.

private void writeFunctionPointerStub(Class c, Method m) {
    ldcClassConstant(c);
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getMethods", "()[Ljava/lang/reflect/Method;");
    mv.visitVarInsn(ASTORE, 7);
    mv.visitInsn(ICONST_0);
    mv.visitVarInsn(ISTORE, 5);
    mv.visitVarInsn(ALOAD, 7);
    mv.visitInsn(ARRAYLENGTH);
    mv.visitVarInsn(ISTORE, 6);
    Label l1 = new Label();
    mv.visitJumpInsn(GOTO, l1);
    Label l2 = new Label();
    mv.visitLabel(l2);
    mv.visitVarInsn(ALOAD, 7);
    mv.visitVarInsn(ILOAD, 5);
    mv.visitInsn(AALOAD);
    mv.visitVarInsn(ASTORE, 4);
    Label l3 = new Label();
    mv.visitLabel(l3);
    mv.visitLdcInsn(m.getName());
    mv.visitVarInsn(ALOAD, 4);
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/reflect/Method", "getName", "()Ljava/lang/String;");
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z");
    Label l4 = new Label();
    mv.visitJumpInsn(IFEQ, l4);
    Label l5 = new Label();
    mv.visitLabel(l5);
    mv.visitVarInsn(ALOAD, 4);
    mv.visitInsn(ARETURN);
    mv.visitLabel(l4);
    mv.visitIincInsn(5, 1);
    mv.visitLabel(l1);
    mv.visitVarInsn(ILOAD, 5);
    mv.visitVarInsn(ILOAD, 6);
    mv.visitJumpInsn(IF_ICMPLT, l2);
    Label l6 = new Label();
    mv.visitLabel(l6);
    mv.visitInsn(ACONST_NULL);
    mv.visitInsn(ARETURN);
// deferFinish = true;
}
Also used : Label(org.mvel2.asm.Label)

Aggregations

Method (java.lang.reflect.Method)6 ExecutableStatement (org.mvel2.compiler.ExecutableStatement)5 Field (java.lang.reflect.Field)4 ArrayLength (org.mvel2.optimizers.impl.refl.nodes.ArrayLength)4 MethodAccessor (org.mvel2.optimizers.impl.refl.nodes.MethodAccessor)4 Map (java.util.Map)3 CompileException (org.mvel2.CompileException)3 OptimizationFailure (org.mvel2.OptimizationFailure)3 PropertyAccessException (org.mvel2.PropertyAccessException)3 Label (org.mvel2.asm.Label)3 ExecutableAccessor (org.mvel2.compiler.ExecutableAccessor)3 ExecutableLiteral (org.mvel2.compiler.ExecutableLiteral)3 FieldAccessor (org.mvel2.optimizers.impl.refl.nodes.FieldAccessor)3 GetterAccessor (org.mvel2.optimizers.impl.refl.nodes.GetterAccessor)3 MapAccessor (org.mvel2.optimizers.impl.refl.nodes.MapAccessor)3 StaticVarAccessor (org.mvel2.optimizers.impl.refl.nodes.StaticVarAccessor)3 ThisValueAccessor (org.mvel2.optimizers.impl.refl.nodes.ThisValueAccessor)3 IOException (java.io.IOException)2 Constructor (java.lang.reflect.Constructor)2 Member (java.lang.reflect.Member)2