Search in sources :

Example 51 with Label

use of org.mvel2.asm.Label in project drools by kiegroup.

the class DefaultBeanClassBuilder method buildConstructorWithFields.

/**
 * Creates a constructor that takes and assigns values to all
 * fields in the order they are declared.
 *
 * @param cw
 * @param classDef
 */
protected void buildConstructorWithFields(ClassVisitor cw, ClassDefinition classDef, Collection<FieldDefinition> fieldDefs) {
    Type[] params = new Type[fieldDefs.size()];
    int index = 0;
    for (FieldDefinition field : fieldDefs) {
        params[index++] = Type.getType(BuildUtils.getTypeDescriptor(field.getTypeName()));
    }
    MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, params), null, null);
    mv.visitCode();
    Label l0 = null;
    if (this.debug) {
        l0 = new Label();
        mv.visitLabel(l0);
    }
    fieldConstructorStart(mv, classDef, fieldDefs);
    mv.visitInsn(Opcodes.RETURN);
    Label l1 = null;
    if (this.debug) {
        l1 = new Label();
        mv.visitLabel(l1);
        mv.visitLocalVariable("this", BuildUtils.getTypeDescriptor(classDef.getClassName()), null, l0, l1, 0);
        for (FieldDefinition field : classDef.getFieldsDefinitions()) {
            Label l11 = new Label();
            mv.visitLabel(l11);
            mv.visitLocalVariable(field.getName(), BuildUtils.getTypeDescriptor(field.getTypeName()), null, l0, l1, 0);
        }
    }
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}
Also used : Type(org.mvel2.asm.Type) FieldDefinition(org.drools.core.factmodel.FieldDefinition) Label(org.mvel2.asm.Label) MethodVisitor(org.mvel2.asm.MethodVisitor)

Example 52 with Label

use of org.mvel2.asm.Label in project drools by kiegroup.

the class DefaultBeanClassBuilder method buildDefaultConstructor.

/**
 * Creates a default constructor for the class
 *
 * @param cw
 */
protected void buildDefaultConstructor(ClassVisitor cw, ClassDefinition classDef) {
    MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}), null, null);
    mv.visitCode();
    Label l0 = null;
    if (this.debug) {
        l0 = new Label();
        mv.visitLabel(l0);
    }
    boolean hasObjects = defaultConstructorStart(mv, classDef);
    mv.visitInsn(Opcodes.RETURN);
    Label l1 = null;
    if (this.debug) {
        l1 = new Label();
        mv.visitLabel(l1);
        mv.visitLocalVariable("this", BuildUtils.getTypeDescriptor(classDef.getClassName()), null, l0, l1, 0);
    }
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}
Also used : Type(org.mvel2.asm.Type) Label(org.mvel2.asm.Label) MethodVisitor(org.mvel2.asm.MethodVisitor)

Example 53 with Label

use of org.mvel2.asm.Label in project drools by kiegroup.

the class ASMEvalStubBuilder method createStubEval.

private void createStubEval(final ClassGenerator generator, final InvokerDataProvider data, final Map vars) {
    generator.setInterfaces(EvalStub.class, CompiledInvoker.class).addField(ACC_PRIVATE + ACC_VOLATILE, "eval", EvalExpression.class);
    generator.addMethod(ACC_PUBLIC, "createContext", generator.methodDescr(Object.class), new ClassGenerator.MethodBody() {

        public void body(MethodVisitor mv) {
            mv.visitInsn(ACONST_NULL);
            mv.visitInsn(ARETURN);
        }
    }).addMethod(ACC_PUBLIC, "clone", generator.methodDescr(EvalExpression.class), new ClassGenerator.MethodBody() {

        public void body(MethodVisitor mv) {
            String internalClassName = generator.getClassName().replace('.', '/');
            mv.visitTypeInsn(NEW, internalClassName);
            mv.visitInsn(DUP);
            mv.visitMethodInsn(INVOKESPECIAL, internalClassName, "<init>", "()V", false);
            mv.visitInsn(ARETURN);
        }
    }).addMethod(ACC_PUBLIC, "replaceDeclaration", generator.methodDescr(null, Declaration.class, Declaration.class)).addMethod(ACC_PUBLIC, "evaluate", generator.methodDescr(Boolean.TYPE, Tuple.class, Declaration[].class, ReteEvaluator.class, Object.class), new String[] { "java/lang/Exception" }, new ClassGenerator.MethodBody() {

        public void body(MethodVisitor mv) {
            Label syncStart = new Label();
            Label syncEnd = new Label();
            Label l1 = new Label();
            Label l2 = new Label();
            mv.visitTryCatchBlock(syncStart, l1, l2, null);
            Label l3 = new Label();
            mv.visitTryCatchBlock(l2, l3, l2, null);
            getFieldFromThis("eval", EvalExpression.class);
            mv.visitJumpInsn(IFNONNULL, syncEnd);
            mv.visitVarInsn(ALOAD, 0);
            mv.visitInsn(DUP);
            mv.visitVarInsn(ASTORE, 5);
            // synchronized(this) {
            mv.visitInsn(MONITORENTER);
            mv.visitLabel(syncStart);
            getFieldFromThis("eval", EvalExpression.class);
            // if (eval == null) ...
            Label ifNotInitialized = new Label();
            mv.visitJumpInsn(IFNONNULL, ifNotInitialized);
            mv.visitVarInsn(ALOAD, 0);
            mv.visitVarInsn(ALOAD, 1);
            mv.visitVarInsn(ALOAD, 2);
            mv.visitVarInsn(ALOAD, 3);
            // ... EvalGenerator.generate(this, tuple, declarations, workingMemory)
            invokeStatic(EvalGenerator.class, "generate", null, EvalStub.class, Tuple.class, Declaration[].class, ReteEvaluator.class);
            mv.visitLabel(ifNotInitialized);
            mv.visitVarInsn(ALOAD, 5);
            mv.visitInsn(MONITOREXIT);
            mv.visitLabel(l1);
            mv.visitJumpInsn(GOTO, syncEnd);
            mv.visitLabel(l2);
            mv.visitVarInsn(ASTORE, 6);
            mv.visitVarInsn(ALOAD, 5);
            mv.visitInsn(MONITOREXIT);
            mv.visitLabel(l3);
            mv.visitVarInsn(ALOAD, 6);
            mv.visitInsn(ATHROW);
            mv.visitLabel(syncEnd);
            // } end of synchronized
            getFieldFromThis("eval", EvalExpression.class);
            mv.visitVarInsn(ALOAD, 1);
            mv.visitVarInsn(ALOAD, 2);
            mv.visitVarInsn(ALOAD, 3);
            mv.visitVarInsn(ALOAD, 4);
            invokeInterface(EvalExpression.class, "evaluate", Boolean.TYPE, Tuple.class, Declaration[].class, ReteEvaluator.class, Object.class);
            mv.visitInsn(IRETURN);
        }
    }).addMethod(ACC_PUBLIC, "setEval", generator.methodDescr(null, EvalExpression.class), new ClassGenerator.MethodBody() {

        public void body(MethodVisitor mv) {
            putFieldInThisFromRegistry("eval", EvalExpression.class, 1);
            mv.visitInsn(RETURN);
        }
    });
}
Also used : EvalExpression(org.drools.core.spi.EvalExpression) Label(org.mvel2.asm.Label) Declaration(org.drools.core.rule.Declaration) CompiledInvoker(org.drools.core.spi.CompiledInvoker) MethodVisitor(org.mvel2.asm.MethodVisitor)

Example 54 with Label

use of org.mvel2.asm.Label in project drools by kiegroup.

the class ASMPredicateStubBuilder method createStubPredicate.

private void createStubPredicate(final ClassGenerator generator, final InvokerDataProvider data, final Map vars) {
    generator.setInterfaces(PredicateStub.class, CompiledInvoker.class).addField(ACC_PRIVATE + ACC_VOLATILE, "predicate", PredicateExpression.class);
    generator.addMethod(ACC_PUBLIC, "createContext", generator.methodDescr(Object.class), new ClassGenerator.MethodBody() {

        public void body(MethodVisitor mv) {
            mv.visitInsn(ACONST_NULL);
            mv.visitInsn(ARETURN);
        }
    }).addMethod(ACC_PUBLIC, "evaluate", generator.methodDescr(Boolean.TYPE, InternalFactHandle.class, Tuple.class, Declaration[].class, Declaration[].class, ReteEvaluator.class, Object.class), new String[] { "java/lang/Exception" }, new ClassGenerator.MethodBody() {

        public void body(MethodVisitor mv) {
            Label syncStart = new Label();
            Label syncEnd = new Label();
            Label l1 = new Label();
            Label l2 = new Label();
            mv.visitTryCatchBlock(syncStart, l1, l2, null);
            Label l3 = new Label();
            mv.visitTryCatchBlock(l2, l3, l2, null);
            getFieldFromThis("predicate", PredicateExpression.class);
            mv.visitJumpInsn(IFNONNULL, syncEnd);
            mv.visitVarInsn(ALOAD, 0);
            mv.visitInsn(DUP);
            mv.visitVarInsn(ASTORE, 7);
            // synchronized(this) {
            mv.visitInsn(MONITORENTER);
            mv.visitLabel(syncStart);
            getFieldFromThis("predicate", PredicateExpression.class);
            // if (predicate == null) ...
            Label ifNotInitialized = new Label();
            mv.visitJumpInsn(IFNONNULL, ifNotInitialized);
            mv.visitVarInsn(ALOAD, 0);
            mv.visitVarInsn(ALOAD, 2);
            mv.visitVarInsn(ALOAD, 3);
            mv.visitVarInsn(ALOAD, 4);
            mv.visitVarInsn(ALOAD, 5);
            // ... PredicateGenerator.generate(this, tuple, declarations, declarations, workingMemory)
            invokeStatic(PredicateGenerator.class, "generate", null, PredicateStub.class, Tuple.class, Declaration[].class, Declaration[].class, ReteEvaluator.class);
            mv.visitLabel(ifNotInitialized);
            mv.visitVarInsn(ALOAD, 7);
            mv.visitInsn(MONITOREXIT);
            mv.visitLabel(l1);
            mv.visitJumpInsn(GOTO, syncEnd);
            mv.visitLabel(l2);
            mv.visitVarInsn(ASTORE, 8);
            mv.visitVarInsn(ALOAD, 7);
            mv.visitInsn(MONITOREXIT);
            mv.visitLabel(l3);
            mv.visitVarInsn(ALOAD, 8);
            mv.visitInsn(ATHROW);
            mv.visitLabel(syncEnd);
            // } end of synchronized
            getFieldFromThis("predicate", PredicateExpression.class);
            mv.visitVarInsn(ALOAD, 1);
            mv.visitVarInsn(ALOAD, 2);
            mv.visitVarInsn(ALOAD, 3);
            mv.visitVarInsn(ALOAD, 4);
            mv.visitVarInsn(ALOAD, 5);
            mv.visitVarInsn(ALOAD, 6);
            invokeInterface(PredicateExpression.class, "evaluate", Boolean.TYPE, InternalFactHandle.class, Tuple.class, Declaration[].class, Declaration[].class, ReteEvaluator.class, Object.class);
            mv.visitInsn(IRETURN);
        }
    }).addMethod(ACC_PUBLIC, "setPredicate", generator.methodDescr(null, PredicateExpression.class), new ClassGenerator.MethodBody() {

        public void body(MethodVisitor mv) {
            putFieldInThisFromRegistry("predicate", PredicateExpression.class, 1);
            mv.visitInsn(RETURN);
        }
    });
}
Also used : Label(org.mvel2.asm.Label) Declaration(org.drools.core.rule.Declaration) PredicateExpression(org.drools.core.spi.PredicateExpression) CompiledInvoker(org.drools.core.spi.CompiledInvoker) MethodVisitor(org.mvel2.asm.MethodVisitor)

Example 55 with Label

use of org.mvel2.asm.Label 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();
                if (es[i] instanceof ExecutableLiteral && ((ExecutableLiteral) es[i]).getLiteral() == null) {
                    argTypes[i] = NullType.class;
                }
            }
        } 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()));
            }
        }
        Class<?> declaringClass = m.getDeclaringClass();
        if (m.getParameterTypes().length == 0) {
            if ((m.getModifiers() & STATIC) != 0) {
                assert debug("INVOKESTATIC " + m.getName());
                mv.visitMethodInsn(INVOKESTATIC, getInternalName(declaringClass), m.getName(), getMethodDescriptor(m));
            } else {
                assert debug("CHECKCAST " + getInternalName(declaringClass));
                mv.visitTypeInsn(CHECKCAST, getInternalName(declaringClass));
                if (declaringClass.isInterface()) {
                    assert debug("INVOKEINTERFACE " + m.getName());
                    mv.visitMethodInsn(INVOKEINTERFACE, getInternalName(declaringClass), m.getName(), getMethodDescriptor(m));
                } else {
                    assert debug("INVOKEVIRTUAL " + m.getName());
                    mv.visitMethodInsn(INVOKEVIRTUAL, getInternalName(declaringClass), m.getName(), getMethodDescriptor(m));
                }
            }
            returnType = m.getReturnType();
            stacksize++;
        } else {
            if ((m.getModifiers() & STATIC) == 0) {
                assert debug("CHECKCAST " + getInternalName(declaringClass));
                mv.visitTypeInsn(CHECKCAST, getInternalName(declaringClass));
            }
            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(c);
                                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.visitVarInsn(ASTORE, 4);
                    Label jmp = new Label();
                    mv.visitVarInsn(ALOAD, 4);
                    mv.visitJumpInsn(IFNONNULL, jmp);
                    mv.visitInsn(ACONST_NULL);
                    Label jmp2 = new Label();
                    mv.visitJumpInsn(GOTO, jmp2);
                    mv.visitLabel(jmp);
                    mv.visitVarInsn(ALOAD, 4);
                    mv.visitMethodInsn(INVOKESTATIC, "java/lang/String", "valueOf", "(Ljava/lang/Object;)Ljava/lang/String;");
                    mv.visitLabel(jmp2);
                } 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.isVarArgs() && (es == null || es.length == (parameterTypes.length - 1))) {
                // The last parameter is a vararg and there is no value, create an empty array array
                createArray(getBaseComponentType(parameterTypes[parameterTypes.length - 1]), 0);
            }
            if ((m.getModifiers() & STATIC) != 0) {
                assert debug("INVOKESTATIC: " + m.getName());
                mv.visitMethodInsn(INVOKESTATIC, getInternalName(declaringClass), m.getName(), getMethodDescriptor(m));
            } else {
                if (declaringClass.isInterface()) {
                    assert debug("INVOKEINTERFACE: " + getInternalName(declaringClass) + "." + m.getName());
                    mv.visitMethodInsn(INVOKEINTERFACE, getInternalName(declaringClass), m.getName(), getMethodDescriptor(m));
                } else {
                    assert debug("INVOKEVIRTUAL: " + getInternalName(declaringClass) + "." + m.getName());
                    mv.visitMethodInsn(INVOKEVIRTUAL, getInternalName(declaringClass), 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 : OptimizationFailure(org.mvel2.OptimizationFailure) ExecutableAccessor(org.mvel2.compiler.ExecutableAccessor) Label(org.mvel2.asm.Label) ExecutableLiteral(org.mvel2.compiler.ExecutableLiteral) StringAppender(org.mvel2.util.StringAppender) CompileException(org.mvel2.CompileException) OptimizationNotSupported(org.mvel2.optimizers.OptimizationNotSupported) ExecutableStatement(org.mvel2.compiler.ExecutableStatement) ParseTools.determineActualTargetMethod(org.mvel2.util.ParseTools.determineActualTargetMethod) Method(java.lang.reflect.Method) FunctionInstance(org.mvel2.ast.FunctionInstance) MethodStub(org.mvel2.util.MethodStub) ParseTools.findClass(org.mvel2.util.ParseTools.findClass)

Aggregations

Label (org.mvel2.asm.Label)97 MethodVisitor (org.mvel2.asm.MethodVisitor)49 FieldDefinition (org.drools.core.factmodel.FieldDefinition)24 Map (java.util.Map)18 Type (org.mvel2.asm.Type)12 IOException (java.io.IOException)10 BitSet (java.util.BitSet)8 FieldVisitor (org.mvel2.asm.FieldVisitor)8 Method (java.lang.reflect.Method)7 CompiledInvoker (org.drools.core.spi.CompiledInvoker)7 TraitableBean (org.drools.core.factmodel.traits.TraitableBean)5 ObjectInput (java.io.ObjectInput)4 ObjectOutput (java.io.ObjectOutput)4 Collection (java.util.Collection)4 Thing (org.drools.core.factmodel.traits.Thing)4 Declaration (org.drools.core.rule.Declaration)4 ClassGenerator (org.drools.core.rule.builder.dialect.asm.ClassGenerator)4 ClassWriter (org.mvel2.asm.ClassWriter)4 ArrayList (java.util.ArrayList)3 HashMap (java.util.HashMap)3