Search in sources :

Example 31 with CompileException

use of org.mule.mvel2.CompileException in project mvel by mvel.

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) {
        return optimizeFieldMethodProperty(ctx, property, cls, member);
    } 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, pCtx);
            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);
        }
        currType = toNonPrimitiveType(returnType);
        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;
                return optimizeFieldMethodProperty(ctx, property, cls, f);
            }
        } 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 (pCtx != null && pCtx.getParserConfiguration() != null ? pCtx.getParserConfiguration().isAllowNakedMethCall() : 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 (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, st, pCtx);
        } else {
            throw new PropertyAccessException("could not access: " + property + "; in class: " + ctx.getClass().getName(), expr, st, pCtx);
        }
    }
}
Also used : OptimizationFailure(org.mvel2.OptimizationFailure) 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) Field(java.lang.reflect.Field) PropertyHandlerFactory.hasNullPropertyHandler(org.mvel2.integration.PropertyHandlerFactory.hasNullPropertyHandler) PropertyHandlerFactory.hasPropertyHandler(org.mvel2.integration.PropertyHandlerFactory.hasPropertyHandler) PropertyHandlerFactory.getPropertyHandler(org.mvel2.integration.PropertyHandlerFactory.getPropertyHandler) PropertyHandler(org.mvel2.integration.PropertyHandler) PropertyHandlerFactory.getNullPropertyHandler(org.mvel2.integration.PropertyHandlerFactory.getNullPropertyHandler) CompileException(org.mvel2.CompileException) Member(java.lang.reflect.Member) Map(java.util.Map)

Example 32 with CompileException

use of org.mule.mvel2.CompileException in project mvel by mvel.

the class ASMAccessorOptimizer method getMethod.

@SuppressWarnings({ "unchecked" })
private Object getMethod(Object ctx, String name) throws IllegalAccessException, InvocationTargetException {
    assert debug("\n  **  {method: " + name + "}");
    int st = cursor;
    String tk = cursor != end && expr[cursor] == '(' && ((cursor = balancedCapture(expr, cursor, '(')) - st) > 1 ? new String(expr, st + 1, cursor - st - 1) : "";
    cursor++;
    Object[] preConvArgs;
    Object[] args;
    Class[] argTypes;
    ExecutableStatement[] es;
    List<char[]> subtokens;
    if (tk.length() == 0) {
        args = preConvArgs = ParseTools.EMPTY_OBJ_ARR;
        argTypes = ParseTools.EMPTY_CLS_ARR;
        es = null;
        subtokens = null;
    } else {
        subtokens = parseParameterList(tk.toCharArray(), 0, -1);
        es = new ExecutableStatement[subtokens.size()];
        args = new Object[subtokens.size()];
        argTypes = new Class[subtokens.size()];
        preConvArgs = new Object[es.length];
        for (int i = 0; i < subtokens.size(); i++) {
            assert debug("subtoken[" + i + "] { " + new String(subtokens.get(i)) + " }");
            preConvArgs[i] = args[i] = (es[i] = (ExecutableStatement) subCompileExpression(subtokens.get(i), pCtx)).getValue(this.thisRef, this.thisRef, variableFactory);
            if (es[i].isExplicitCast())
                argTypes[i] = es[i].getKnownEgressType();
        }
        if (pCtx.isStrictTypeEnforcement()) {
            for (int i = 0; i < args.length; i++) {
                argTypes[i] = es[i].getKnownEgressType();
            }
        } else {
            for (int i = 0; i < args.length; i++) {
                if (argTypes[i] != null)
                    continue;
                if (es[i].getKnownEgressType() == Object.class) {
                    argTypes[i] = args[i] == null ? null : args[i].getClass();
                } else {
                    argTypes[i] = es[i].getKnownEgressType();
                }
            }
        }
    }
    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) {
            if (es != null && es.length != 0) {
                compiledInputs.addAll(Arrays.asList(es));
                intPush(es.length);
                assert debug("ANEWARRAY [" + es.length + "]");
                mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
                assert debug("ASTORE 4");
                mv.visitVarInsn(ASTORE, 4);
                for (int i = 0; i < es.length; i++) {
                    assert debug("ALOAD 4");
                    mv.visitVarInsn(ALOAD, 4);
                    intPush(i);
                    loadField(i);
                    assert debug("ALOAD 1");
                    mv.visitVarInsn(ALOAD, 1);
                    assert debug("ALOAD 3");
                    mv.visitIntInsn(ALOAD, 3);
                    assert debug("INVOKEINTERFACE ExecutableStatement.getValue");
                    mv.visitMethodInsn(INVOKEINTERFACE, NAMESPACE + "compiler/ExecutableStatement", "getValue", "(Ljava/lang/Object;L" + NAMESPACE + "integration/VariableResolverFactory;)Ljava/lang/Object;");
                    assert debug("AASTORE");
                    mv.visitInsn(AASTORE);
                }
            } else {
                assert debug("ACONST_NULL");
                mv.visitInsn(ACONST_NULL);
                assert debug("CHECKCAST java/lang/Object");
                mv.visitTypeInsn(CHECKCAST, "[Ljava/lang/Object;");
                assert debug("ASTORE 4");
                mv.visitVarInsn(ASTORE, 4);
            }
            if (variableFactory.isIndexedFactory() && variableFactory.isTarget(name)) {
                loadVariableByIndex(variableFactory.variableIndexOf(name));
            } else {
                loadVariableByName(name);
            }
            checkcast(FunctionInstance.class);
            assert debug("ALOAD 1");
            mv.visitVarInsn(ALOAD, 1);
            assert debug("ALOAD 2");
            mv.visitVarInsn(ALOAD, 2);
            assert debug("ALOAD 3");
            mv.visitVarInsn(ALOAD, 3);
            assert debug("ALOAD 4");
            mv.visitVarInsn(ALOAD, 4);
            assert debug("INVOKEVIRTUAL Function.call");
            mv.visitMethodInsn(INVOKEVIRTUAL, getInternalName(FunctionInstance.class), "call", "(Ljava/lang/Object;Ljava/lang/Object;L" + NAMESPACE + "integration/VariableResolverFactory;[Ljava/lang/Object;)Ljava/lang/Object;");
            return ((FunctionInstance) ptr).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;
    } else if (returnType != null && returnType.isPrimitive()) {
        // noinspection unchecked
        wrapPrimitive(returnType);
    }
    /**
     * If the target object is an instance of java.lang.Class itself then do not
     * adjust the Class scope target.
     */
    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 && cls != ctx.getClass() && !(ctx instanceof Class)) {
        cls = ctx.getClass();
        if ((m = getBestCandidate(argTypes, name, cls, cls.getMethods(), false, classTarget)) != null) {
            parameterTypes = m.getParameterTypes();
        }
    }
    if (es != null && m != null && m.isVarArgs() && (es.length != parameterTypes.length || !(es[es.length - 1] instanceof ExecutableAccessor))) {
        // normalize ExecutableStatement for varargs
        ExecutableStatement[] varArgEs = new ExecutableStatement[parameterTypes.length];
        int varArgStart = parameterTypes.length - 1;
        for (int i = 0; i < varArgStart; i++) varArgEs[i] = es[i];
        String varargsTypeName = parameterTypes[parameterTypes.length - 1].getComponentType().getName();
        String varArgExpr;
        if ("null".equals(tk)) {
            // if null is the token no need for wrapping
            varArgExpr = tk;
        } else {
            StringBuilder sb = new StringBuilder("new ").append(varargsTypeName).append("[] {");
            for (int i = varArgStart; i < subtokens.size(); i++) {
                sb.append(subtokens.get(i));
                if (i < subtokens.size() - 1)
                    sb.append(",");
            }
            varArgExpr = sb.append("}").toString();
        }
        char[] token = varArgExpr.toCharArray();
        varArgEs[varArgStart] = ((ExecutableStatement) subCompileExpression(token, pCtx));
        es = varArgEs;
        if (preConvArgs.length == parameterTypes.length - 1) {
            // empty vararg
            Object[] preConvArgsForVarArg = new Object[parameterTypes.length];
            for (int i = 0; i < preConvArgs.length; i++) preConvArgsForVarArg[i] = preConvArgs[i];
            preConvArgsForVarArg[parameterTypes.length - 1] = Array.newInstance(parameterTypes[parameterTypes.length - 1].getComponentType(), 0);
            preConvArgs = preConvArgsForVarArg;
        }
    }
    int inputsOffset = compiledInputs.size();
    if (es != null) {
        for (ExecutableStatement e : es) {
            if (e instanceof ExecutableLiteral) {
                continue;
            }
            compiledInputs.add(e);
        }
    }
    if (first) {
        assert debug("ALOAD 1 (D) ");
        mv.visitVarInsn(ALOAD, 1);
    }
    if (m == null) {
        StringAppender errorBuild = new StringAppender();
        if (parameterTypes != null) {
            for (int i = 0; i < args.length; i++) {
                errorBuild.append(parameterTypes[i] != null ? parameterTypes[i].getClass().getName() : null);
                if (i < args.length - 1)
                    errorBuild.append(", ");
            }
        }
        if ("size".equals(name) && args.length == 0 && cls.isArray()) {
            anyArrayCheck(cls);
            assert debug("ARRAYLENGTH");
            mv.visitInsn(ARRAYLENGTH);
            wrapPrimitive(int.class);
            return getLength(ctx);
        }
        throw new CompileException("unable to resolve method: " + cls.getName() + "." + name + "(" + errorBuild.toString() + ") [arglength=" + args.length + "]", expr, st);
    } else {
        m = getWidenedTarget(m);
        if (es != null) {
            ExecutableStatement cExpr;
            for (int i = 0; i < es.length; i++) {
                if ((cExpr = es[i]).getKnownIngressType() == null) {
                    cExpr.setKnownIngressType(parameterTypes[i]);
                    cExpr.computeTypeConversionRule();
                }
                if (!cExpr.isConvertableIngressEgress() && i < args.length) {
                    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()));
            }
        }
        if (m.getParameterTypes().length == 0) {
            if ((m.getModifiers() & STATIC) != 0) {
                assert debug("INVOKESTATIC " + m.getName());
                mv.visitMethodInsn(INVOKESTATIC, getInternalName(m.getDeclaringClass()), m.getName(), getMethodDescriptor(m));
            } else {
                assert debug("CHECKCAST " + getInternalName(m.getDeclaringClass()));
                mv.visitTypeInsn(CHECKCAST, getInternalName(m.getDeclaringClass()));
                if (m.getDeclaringClass().isInterface()) {
                    assert debug("INVOKEINTERFACE " + m.getName());
                    mv.visitMethodInsn(INVOKEINTERFACE, getInternalName(m.getDeclaringClass()), m.getName(), getMethodDescriptor(m));
                } else {
                    assert debug("INVOKEVIRTUAL " + m.getName());
                    mv.visitMethodInsn(INVOKEVIRTUAL, getInternalName(m.getDeclaringClass()), m.getName(), getMethodDescriptor(m));
                }
            }
            returnType = m.getReturnType();
            stacksize++;
        } else {
            if ((m.getModifiers() & STATIC) == 0) {
                assert debug("CHECKCAST " + getInternalName(cls));
                mv.visitTypeInsn(CHECKCAST, getInternalName(cls));
            }
            Class<?> aClass = m.getParameterTypes()[m.getParameterTypes().length - 1];
            if (m.isVarArgs()) {
                if (es == null || es.length == (m.getParameterTypes().length - 1)) {
                    ExecutableStatement[] executableStatements = new ExecutableStatement[m.getParameterTypes().length];
                    if (es != null) {
                        System.arraycopy(es, 0, executableStatements, 0, es.length);
                    }
                    executableStatements[executableStatements.length - 1] = new ExecutableLiteral(Array.newInstance(aClass, 0));
                    es = executableStatements;
                }
            }
            for (int i = 0; es != null && i < es.length; i++) {
                if (es[i] instanceof ExecutableLiteral) {
                    ExecutableLiteral literal = (ExecutableLiteral) es[i];
                    if (literal.getLiteral() == null) {
                        assert debug("ICONST_NULL");
                        mv.visitInsn(ACONST_NULL);
                        continue;
                    } else if (parameterTypes[i] == int.class && literal.intOptimized()) {
                        intPush(literal.getInteger32());
                        continue;
                    } else if (parameterTypes[i] == int.class && preConvArgs[i] instanceof Integer) {
                        intPush((Integer) preConvArgs[i]);
                        continue;
                    } else if (parameterTypes[i] == boolean.class) {
                        boolean bool = DataConversion.convert(literal.getLiteral(), Boolean.class);
                        assert debug(bool ? "ICONST_1" : "ICONST_0");
                        mv.visitInsn(bool ? ICONST_1 : ICONST_0);
                        continue;
                    } else {
                        Object lit = literal.getLiteral();
                        if (parameterTypes[i] == Object.class) {
                            if (isPrimitiveWrapper(lit.getClass())) {
                                if (lit.getClass() == Integer.class) {
                                    intPush((Integer) lit);
                                } else {
                                    assert debug("LDC " + lit);
                                    mv.visitLdcInsn(lit);
                                }
                                wrapPrimitive(lit.getClass());
                            } else if (lit instanceof String) {
                                mv.visitLdcInsn(lit);
                                checkcast(Object.class);
                            }
                            continue;
                        } else if (canConvert(parameterTypes[i], lit.getClass())) {
                            Object c = convert(lit, parameterTypes[i]);
                            if (c instanceof Class) {
                                ldcClassConstant((Class) c);
                            } else {
                                assert debug("LDC " + lit + " (" + lit.getClass().getName() + ")");
                                mv.visitLdcInsn(convert(lit, parameterTypes[i]));
                                if (isPrimitiveWrapper(parameterTypes[i])) {
                                    wrapPrimitive(lit.getClass());
                                }
                            }
                            continue;
                        } else {
                            throw new OptimizationNotSupported();
                        }
                    }
                }
                assert debug("ALOAD 0");
                mv.visitVarInsn(ALOAD, 0);
                assert debug("GETFIELD p" + inputsOffset);
                mv.visitFieldInsn(GETFIELD, className, "p" + inputsOffset, "L" + NAMESPACE + "compiler/ExecutableStatement;");
                inputsOffset++;
                assert debug("ALOAD 2");
                mv.visitVarInsn(ALOAD, 2);
                assert debug("ALOAD 3");
                mv.visitVarInsn(ALOAD, 3);
                assert debug("INVOKEINTERFACE ExecutableStatement.getValue");
                mv.visitMethodInsn(INVOKEINTERFACE, getInternalName(ExecutableStatement.class), "getValue", "(Ljava/lang/Object;L" + NAMESPACE + "integration/VariableResolverFactory;)Ljava/lang/Object;");
                if (parameterTypes[i].isPrimitive()) {
                    if (preConvArgs[i] == null || (parameterTypes[i] != String.class && !parameterTypes[i].isAssignableFrom(preConvArgs[i].getClass()))) {
                        ldcClassConstant(getWrapperClass(parameterTypes[i]));
                        assert debug("INVOKESTATIC DataConversion.convert");
                        mv.visitMethodInsn(INVOKESTATIC, NAMESPACE + "DataConversion", "convert", "(Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;");
                    }
                    unwrapPrimitive(parameterTypes[i]);
                } else if (preConvArgs[i] == null || (parameterTypes[i] != String.class && !parameterTypes[i].isAssignableFrom(preConvArgs[i].getClass()))) {
                    ldcClassConstant(parameterTypes[i]);
                    assert debug("INVOKESTATIC DataConversion.convert");
                    mv.visitMethodInsn(INVOKESTATIC, NAMESPACE + "DataConversion", "convert", "(Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;");
                    assert debug("CHECKCAST " + getInternalName(parameterTypes[i]));
                    mv.visitTypeInsn(CHECKCAST, getInternalName(parameterTypes[i]));
                } else if (parameterTypes[i] == String.class) {
                    assert debug("<<<DYNAMIC TYPE OPTIMIZATION STRING>>");
                    mv.visitMethodInsn(INVOKESTATIC, "java/lang/String", "valueOf", "(Ljava/lang/Object;)Ljava/lang/String;");
                } else {
                    assert debug("<<<DYNAMIC TYPING BYPASS>>>");
                    assert debug("<<<OPT. JUSTIFICATION " + parameterTypes[i] + "=" + preConvArgs[i].getClass() + ">>>");
                    assert debug("CHECKCAST " + getInternalName(parameterTypes[i]));
                    mv.visitTypeInsn(CHECKCAST, getInternalName(parameterTypes[i]));
                }
            }
            if ((m.getModifiers() & STATIC) != 0) {
                assert debug("INVOKESTATIC: " + m.getName());
                mv.visitMethodInsn(INVOKESTATIC, getInternalName(m.getDeclaringClass()), m.getName(), getMethodDescriptor(m));
            } else {
                if (m.getDeclaringClass().isInterface() && (m.getDeclaringClass() != cls || (ctx != null && ctx.getClass() != m.getDeclaringClass()))) {
                    assert debug("INVOKEINTERFACE: " + getInternalName(m.getDeclaringClass()) + "." + m.getName());
                    mv.visitMethodInsn(INVOKEINTERFACE, getInternalName(m.getDeclaringClass()), m.getName(), getMethodDescriptor(m));
                } else {
                    assert debug("INVOKEVIRTUAL: " + getInternalName(cls) + "." + m.getName());
                    mv.visitMethodInsn(INVOKEVIRTUAL, getInternalName(cls), m.getName(), getMethodDescriptor(m));
                }
            }
            returnType = m.getReturnType();
            stacksize++;
        }
        Object o = m.invoke(ctx, normalizeArgsForVarArgs(parameterTypes, args, m.isVarArgs()));
        if (hasNullMethodHandler()) {
            writeOutNullHandler(m, 1);
            if (o == null)
                o = getNullMethodHandler().getProperty(m.getName(), ctx, variableFactory);
        }
        currType = toNonPrimitiveType(m.getReturnType());
        return o;
    }
}
Also used : ExecutableStatement(org.mvel2.compiler.ExecutableStatement) OptimizationFailure(org.mvel2.OptimizationFailure) ExecutableAccessor(org.mvel2.compiler.ExecutableAccessor) Method(java.lang.reflect.Method) FunctionInstance(org.mvel2.ast.FunctionInstance) MethodStub(org.mvel2.util.MethodStub) ExecutableLiteral(org.mvel2.compiler.ExecutableLiteral) StringAppender(org.mvel2.util.StringAppender) CompileException(org.mvel2.CompileException) OptimizationNotSupported(org.mvel2.optimizers.OptimizationNotSupported)

Example 33 with CompileException

use of org.mule.mvel2.CompileException in project mvel by mvel.

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;
    }
    currType = 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 + ">>}");
    if (ctx == null)
        return null;
    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 : ExecutableStatement(org.mvel2.compiler.ExecutableStatement) TypeDescriptor(org.mvel2.ast.TypeDescriptor) CompileException(org.mvel2.CompileException) List(java.util.List) ArrayList(java.util.ArrayList) Map(java.util.Map) CompileException(org.mvel2.CompileException) InvocationTargetException(java.lang.reflect.InvocationTargetException) PropertyAccessException(org.mvel2.PropertyAccessException) IOException(java.io.IOException)

Example 34 with CompileException

use of org.mule.mvel2.CompileException in project mvel by mvel.

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(pCtx, 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(pCtx, 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 : ExecutableStatement(org.mvel2.compiler.ExecutableStatement) Constructor(java.lang.reflect.Constructor) OptimizationFailure(org.mvel2.OptimizationFailure) ExecutableAccessor(org.mvel2.compiler.ExecutableAccessor) Accessor(org.mvel2.compiler.Accessor) PropertyTools.getFieldOrWriteAccessor(org.mvel2.util.PropertyTools.getFieldOrWriteAccessor) PropertyTools.getFieldOrAccessor(org.mvel2.util.PropertyTools.getFieldOrAccessor) Union(org.mvel2.optimizers.impl.refl.nodes.Union) CompileException(org.mvel2.CompileException) InvocationTargetException(java.lang.reflect.InvocationTargetException) PropertyAccessException(org.mvel2.PropertyAccessException) IOException(java.io.IOException) CompileException(org.mvel2.CompileException)

Example 35 with CompileException

use of org.mule.mvel2.CompileException in project mvel by mvel.

the class ReflectiveAccessorOptimizer method compileConstructor.

@SuppressWarnings({ "WeakerAccess" })
private 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], paramTypeVarArgsSafe(cns.getParameterTypes(), i, cns.isVarArgs()));
        }
        parms = normalizeArgsForVarArgs(cns.getParameterTypes(), parms, cns.isVarArgs());
        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 {
        ClassLoader classLoader = pCtx != null ? pCtx.getClassLoader() : currentThread().getContextClassLoader();
        Constructor<?> cns = Class.forName(new String(expression), true, classLoader).getConstructor(EMPTYCLS);
        AccessorNode ca = new ConstructorAccessor(cns, null);
        if (cnsRes.length > 1) {
            // noinspection NullArgumentToVariableArgMethod
            ReflectiveAccessorOptimizer compiledOptimizer = new ReflectiveAccessorOptimizer(pCtx, 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) Constructor(java.lang.reflect.Constructor) AccessorNode(org.mvel2.compiler.AccessorNode) CompileException(org.mvel2.CompileException) ConstructorAccessor(org.mvel2.optimizers.impl.refl.nodes.ConstructorAccessor)

Aggregations

CompileException (org.mvel2.CompileException)83 ParserContext (org.mvel2.ParserContext)14 Map (java.util.Map)13 ExecutableStatement (org.mvel2.compiler.ExecutableStatement)13 PropertyAccessException (org.mvel2.PropertyAccessException)12 InvocationTargetException (java.lang.reflect.InvocationTargetException)11 List (java.util.List)11 ArrayList (java.util.ArrayList)10 IOException (java.io.IOException)9 Method (java.lang.reflect.Method)7 TypeDescriptor (org.mvel2.ast.TypeDescriptor)7 Field (java.lang.reflect.Field)6 HashMap (java.util.HashMap)6 EndOfStatement (org.mvel2.ast.EndOfStatement)6 Proto (org.mvel2.ast.Proto)6 Constructor (java.lang.reflect.Constructor)5 Member (java.lang.reflect.Member)5 ASTNode (org.mvel2.ast.ASTNode)5 LiteralNode (org.mvel2.ast.LiteralNode)5 Collection (java.util.Collection)4