Search in sources :

Example 81 with Label

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

the class MVELConstraintBuilder method setExprInputs.

@Override
public void setExprInputs(RuleBuildContext context, PatternBuilder.ExprBindings descrBranch, Class<?> thisClass, String expr) {
    MVELDialectRuntimeData data = (MVELDialectRuntimeData) context.getPkg().getDialectRuntimeRegistry().getDialectData("mvel");
    ParserConfiguration conf = data.getParserConfiguration();
    conf.setClassLoader(context.getKnowledgeBuilder().getRootClassLoader());
    final ParserContext pctx = new ParserContext(conf);
    pctx.setStrictTypeEnforcement(false);
    pctx.setStrongTyping(false);
    pctx.addInput("this", thisClass);
    // overrides the mvel empty label
    pctx.addInput("empty", boolean.class);
    MVEL.COMPILER_OPT_ALLOW_NAKED_METH_CALL = true;
    MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING = true;
    MVEL.COMPILER_OPT_ALLOW_RESOLVE_INNERCLASSES_WITH_DOTNOTATION = true;
    MVEL.COMPILER_OPT_SUPPORT_JAVA_STYLE_CLASS_LITERALS = true;
    try {
        MVEL.analysisCompile(expr, pctx);
    } catch (Exception e) {
        // reported during expression analysis, so swallow it at the moment
        return;
    }
    if (!pctx.getInputs().isEmpty()) {
        for (String v : pctx.getInputs().keySet()) {
            // to an "empty" property, or the if will evaluate to true even if it doesn't
            if ("this".equals(v) || (PropertyTools.getFieldOrAccessor(thisClass, v) != null && expr.matches("(^|.*\\W)empty($|\\W.*)"))) {
                descrBranch.getFieldAccessors().add(v);
            } else if ("empty".equals(v)) {
            // do nothing
            } else if (!context.getPkg().getGlobals().containsKey(v)) {
                descrBranch.getRuleBindings().add(v);
            } else {
                descrBranch.getGlobalBindings().add(v);
            }
        }
    }
}
Also used : ParserContext(org.mvel2.ParserContext) IOException(java.io.IOException) ParserConfiguration(org.mvel2.ParserConfiguration)

Example 82 with Label

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

the class ClassFieldAccessorFactory method buildSetMethod.

/**
 * Creates the set method for the given field definition
 */
protected static void buildSetMethod(final Class<?> originalClass, final String className, final Class<?> superClass, final Method setterMethod, final Class<?> fieldType, final ClassWriter cw) {
    MethodVisitor mv;
    // set method
    Method overridingMethod;
    try {
        overridingMethod = superClass.getMethod(getOverridingSetMethodName(fieldType), Object.class, fieldType.isPrimitive() ? fieldType : Object.class);
    } catch (final Exception e) {
        throw new RuntimeException("This is a bug. Please report back to JBoss Rules team.", e);
    }
    mv = cw.visitMethod(Opcodes.ACC_PUBLIC, overridingMethod.getName(), Type.getMethodDescriptor(overridingMethod), null, null);
    mv.visitCode();
    final Label l0 = new Label();
    mv.visitLabel(l0);
    mv.visitVarInsn(Opcodes.ALOAD, 1);
    mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(originalClass));
    mv.visitVarInsn(Type.getType(fieldType).getOpcode(Opcodes.ILOAD), 2);
    if (!fieldType.isPrimitive()) {
        mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(fieldType));
    }
    if (originalClass.isInterface()) {
        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getInternalName(originalClass), setterMethod.getName(), Type.getMethodDescriptor(setterMethod), true);
    } else {
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(originalClass), setterMethod.getName(), Type.getMethodDescriptor(setterMethod), false);
    }
    mv.visitInsn(Opcodes.RETURN);
    final Label l1 = new Label();
    mv.visitLabel(l1);
    mv.visitLocalVariable("this", "L" + className + ";", null, l0, l1, 0);
    mv.visitLocalVariable("bean", Type.getDescriptor(Object.class), null, l0, l1, 1);
    mv.visitLocalVariable("value", Type.getDescriptor(fieldType), null, l0, l1, 2);
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}
Also used : Label(org.mvel2.asm.Label) Method(java.lang.reflect.Method) MethodVisitor(org.mvel2.asm.MethodVisitor)

Example 83 with Label

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

the class ASMConsequenceStubBuilder method createStubConsequence.

private void createStubConsequence(final ClassGenerator generator, final InvokerDataProvider data, final Map<String, Object> vars) {
    generator.setInterfaces(ConsequenceStub.class, CompiledInvoker.class).addField(ACC_PRIVATE + ACC_VOLATILE, "consequence", Consequence.class);
    generator.addMethod(ACC_PUBLIC, "getName", generator.methodDescr(String.class), new ClassGenerator.MethodBody() {

        public void body(MethodVisitor mv) {
            push((String) vars.get("consequenceName"));
            // return the first object on the stack
            mv.visitInsn(ARETURN);
        }
    }).addMethod(ACC_PUBLIC, "getNotPatterns", generator.methodDescr(Boolean[].class), new ClassGenerator.MethodBody() {

        public void body(MethodVisitor mv) {
            returnAsArray((Boolean[]) vars.get("notPatterns"));
        }
    }).addMethod(ACC_PUBLIC, "evaluate", generator.methodDescr(null, KnowledgeHelper.class, ReteEvaluator.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("consequence", Consequence.class);
            mv.visitJumpInsn(IFNONNULL, syncEnd);
            mv.visitVarInsn(ALOAD, 0);
            mv.visitInsn(DUP);
            mv.visitVarInsn(ASTORE, 3);
            // synchronized(this) {
            mv.visitInsn(MONITORENTER);
            mv.visitLabel(syncStart);
            getFieldFromThis("consequence", Consequence.class);
            // if (consequence == null) ...
            Label ifNotInitialized = new Label();
            mv.visitJumpInsn(IFNONNULL, ifNotInitialized);
            mv.visitVarInsn(ALOAD, 0);
            mv.visitVarInsn(ALOAD, 1);
            mv.visitVarInsn(ALOAD, 2);
            // ... ConsequenceGenerator.generate(this, knowledgeHelper, workingMemory)
            invokeStatic(ConsequenceGenerator.class, "generate", null, ConsequenceStub.class, KnowledgeHelper.class, ReteEvaluator.class);
            mv.visitLabel(ifNotInitialized);
            mv.visitVarInsn(ALOAD, 3);
            mv.visitInsn(MONITOREXIT);
            mv.visitLabel(l1);
            mv.visitJumpInsn(GOTO, syncEnd);
            mv.visitLabel(l2);
            mv.visitVarInsn(ASTORE, 4);
            mv.visitVarInsn(ALOAD, 3);
            mv.visitInsn(MONITOREXIT);
            mv.visitLabel(l3);
            mv.visitVarInsn(ALOAD, 4);
            mv.visitInsn(ATHROW);
            mv.visitLabel(syncEnd);
            // } end of synchronized
            getFieldFromThis("consequence", Consequence.class);
            mv.visitVarInsn(ALOAD, 1);
            mv.visitVarInsn(ALOAD, 2);
            invokeInterface(Consequence.class, "evaluate", null, KnowledgeHelper.class, ReteEvaluator.class);
            mv.visitInsn(RETURN);
        }
    }).addMethod(ACC_PUBLIC, "setConsequence", generator.methodDescr(null, Consequence.class), new ClassGenerator.MethodBody() {

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

Example 84 with Label

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

the class DefaultBeanClassBuilder method buildEquals.

protected void buildEquals(ClassVisitor cw, ClassDefinition classDef) {
    MethodVisitor mv;
    // Building equals method
    {
        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "equals", "(Ljava/lang/Object;)Z", null, null);
        mv.visitCode();
        Label l0 = null;
        if (this.debug) {
            l0 = new Label();
            mv.visitLabel(l0);
        }
        // if ( this == obj ) return true;
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitVarInsn(Opcodes.ALOAD, 1);
        Label l1 = new Label();
        mv.visitJumpInsn(Opcodes.IF_ACMPNE, l1);
        mv.visitInsn(Opcodes.ICONST_1);
        mv.visitInsn(Opcodes.IRETURN);
        // if ( obj == null ) return false;
        mv.visitLabel(l1);
        mv.visitVarInsn(Opcodes.ALOAD, 1);
        Label l2 = new Label();
        mv.visitJumpInsn(Opcodes.IFNONNULL, l2);
        mv.visitInsn(Opcodes.ICONST_0);
        mv.visitInsn(Opcodes.IRETURN);
        // if ( getClass() != obj.getClass() ) return false;
        mv.visitLabel(l2);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Object.class), "getClass", Type.getMethodDescriptor(Type.getType(Class.class), new Type[] {}));
        mv.visitVarInsn(Opcodes.ALOAD, 1);
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Object.class), "getClass", Type.getMethodDescriptor(Type.getType(Class.class), new Type[] {}));
        Label l3 = new Label();
        mv.visitJumpInsn(Opcodes.IF_ACMPEQ, l3);
        mv.visitInsn(Opcodes.ICONST_0);
        mv.visitInsn(Opcodes.IRETURN);
        // final <classname> other = (<classname>) obj;
        mv.visitLabel(l3);
        mv.visitVarInsn(Opcodes.ALOAD, 1);
        mv.visitTypeInsn(Opcodes.CHECKCAST, BuildUtils.getInternalType(classDef.getClassName()));
        mv.visitVarInsn(Opcodes.ASTORE, 2);
        // for each key field
        int count = 0;
        for (FieldDefinition field : classDef.getFieldsDefinitions()) {
            if (field.isKey()) {
                count++;
                Label goNext = new Label();
                if (BuildUtils.isPrimitive(field.getTypeName())) {
                    // if attr is primitive
                    // if ( this.<attr> != other.<booleanAttr> ) return false;
                    mv.visitVarInsn(Opcodes.ALOAD, 0);
                    visitFieldOrGetter(mv, classDef, field);
                    mv.visitVarInsn(Opcodes.ALOAD, 2);
                    visitFieldOrGetter(mv, classDef, field);
                    if (field.getTypeName().equals("long")) {
                        mv.visitInsn(Opcodes.LCMP);
                        mv.visitJumpInsn(Opcodes.IFEQ, goNext);
                    } else if (field.getTypeName().equals("double")) {
                        mv.visitInsn(Opcodes.DCMPL);
                        mv.visitJumpInsn(Opcodes.IFEQ, goNext);
                    } else if (field.getTypeName().equals("float")) {
                        mv.visitInsn(Opcodes.FCMPL);
                        mv.visitJumpInsn(Opcodes.IFEQ, goNext);
                    } else {
                        // boolean, byte, char, short, int
                        mv.visitJumpInsn(Opcodes.IF_ICMPEQ, goNext);
                    }
                    mv.visitInsn(Opcodes.ICONST_0);
                    mv.visitInsn(Opcodes.IRETURN);
                } else {
                    // if attr is not a primitive
                    // if ( this.<attr> == null && other.<attr> != null ||
                    // this.<attr> != null && ! this.<attr>.equals( other.<attr> ) ) return false;
                    mv.visitVarInsn(Opcodes.ALOAD, 0);
                    visitFieldOrGetter(mv, classDef, field);
                    Label secondIfPart = new Label();
                    mv.visitJumpInsn(Opcodes.IFNONNULL, secondIfPart);
                    // if ( other.objAttr != null ) return false;
                    mv.visitVarInsn(Opcodes.ALOAD, 2);
                    visitFieldOrGetter(mv, classDef, field);
                    Label returnFalse = new Label();
                    mv.visitJumpInsn(Opcodes.IFNONNULL, returnFalse);
                    mv.visitLabel(secondIfPart);
                    mv.visitVarInsn(Opcodes.ALOAD, 0);
                    visitFieldOrGetter(mv, classDef, field);
                    mv.visitJumpInsn(Opcodes.IFNULL, goNext);
                    mv.visitVarInsn(Opcodes.ALOAD, 0);
                    visitFieldOrGetter(mv, classDef, field);
                    mv.visitVarInsn(Opcodes.ALOAD, 2);
                    visitFieldOrGetter(mv, classDef, field);
                    if (!BuildUtils.isArray(field.getTypeName())) {
                        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z");
                    } else {
                        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/util/Arrays", "equals", "(" + BuildUtils.arrayType(field.getTypeName()) + BuildUtils.arrayType(field.getTypeName()) + ")Z");
                    }
                    mv.visitJumpInsn(Opcodes.IFNE, goNext);
                    mv.visitLabel(returnFalse);
                    mv.visitInsn(Opcodes.ICONST_0);
                    mv.visitInsn(Opcodes.IRETURN);
                }
                mv.visitLabel(goNext);
            }
        }
        if (count > 0) {
            mv.visitInsn(Opcodes.ICONST_1);
        } else {
            mv.visitInsn(Opcodes.ICONST_0);
        }
        mv.visitInsn(Opcodes.IRETURN);
        Label lastLabel = null;
        if (this.debug) {
            lastLabel = new Label();
            mv.visitLabel(lastLabel);
            mv.visitLocalVariable("this", BuildUtils.getTypeDescriptor(classDef.getClassName()), null, l0, lastLabel, 0);
            mv.visitLocalVariable("obj", Type.getDescriptor(Object.class), null, l0, lastLabel, 1);
            mv.visitLocalVariable("other", BuildUtils.getTypeDescriptor(classDef.getClassName()), null, l0, lastLabel, 2);
        }
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }
}
Also used : FieldDefinition(org.drools.core.factmodel.FieldDefinition) Label(org.mvel2.asm.Label) MethodVisitor(org.mvel2.asm.MethodVisitor)

Example 85 with Label

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

the class DefaultBeanClassBuilder method buildHashCode.

protected void buildHashCode(ClassVisitor cw, ClassDefinition classDef) {
    MethodVisitor mv;
    // Building hashCode() method
    {
        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "hashCode", "()I", null, null);
        mv.visitCode();
        Label l0 = null;
        if (this.debug) {
            l0 = new Label();
            mv.visitLabel(l0);
        }
        // int result = 1;
        mv.visitInsn(Opcodes.ICONST_1);
        mv.visitVarInsn(Opcodes.ISTORE, 1);
        // for each key field
        for (FieldDefinition field : classDef.getFieldsDefinitions()) {
            if (field.isKey()) {
                // result = result * 31 + <attr_hash>
                mv.visitVarInsn(Opcodes.ILOAD, 1);
                mv.visitIntInsn(Opcodes.BIPUSH, 31);
                mv.visitVarInsn(Opcodes.ILOAD, 1);
                mv.visitInsn(Opcodes.IMUL);
                mv.visitVarInsn(Opcodes.ALOAD, 0);
                visitFieldOrGetter(mv, classDef, field);
                if ("boolean".equals(field.getTypeName())) {
                    // attr_hash ::== <boolean_attr> ? 1231 : 1237;
                    Label blabel1 = new Label();
                    mv.visitJumpInsn(Opcodes.IFEQ, blabel1);
                    mv.visitIntInsn(Opcodes.SIPUSH, 1231);
                    Label blabel2 = new Label();
                    mv.visitJumpInsn(Opcodes.GOTO, blabel2);
                    mv.visitLabel(blabel1);
                    mv.visitIntInsn(Opcodes.SIPUSH, 1237);
                    mv.visitLabel(blabel2);
                } else if ("long".equals(field.getTypeName())) {
                    // attr_hash ::== (int) (longAttr ^ (longAttr >>> 32))
                    mv.visitVarInsn(Opcodes.ALOAD, 0);
                    visitFieldOrGetter(mv, classDef, field);
                    mv.visitIntInsn(Opcodes.BIPUSH, 32);
                    mv.visitInsn(Opcodes.LUSHR);
                    mv.visitInsn(Opcodes.LXOR);
                    mv.visitInsn(Opcodes.L2I);
                } else if ("float".equals(field.getTypeName())) {
                    // attr_hash ::== Float.floatToIntBits( floatAttr );
                    mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(Float.class), "floatToIntBits", "(F)I");
                } else if ("double".equals(field.getTypeName())) {
                    // attr_hash ::== (int) (Double.doubleToLongBits( doubleAttr ) ^ (Double.doubleToLongBits( doubleAttr ) >>> 32));
                    mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(Double.class), "doubleToLongBits", "(D)J");
                    mv.visitInsn(Opcodes.DUP2);
                    mv.visitIntInsn(Opcodes.BIPUSH, 32);
                    mv.visitInsn(Opcodes.LUSHR);
                    mv.visitInsn(Opcodes.LXOR);
                    mv.visitInsn(Opcodes.L2I);
                } else if (!BuildUtils.isPrimitive(field.getTypeName())) {
                    // attr_hash ::== ((objAttr == null) ? 0 : objAttr.hashCode());
                    Label olabel1 = new Label();
                    mv.visitJumpInsn(Opcodes.IFNONNULL, olabel1);
                    mv.visitInsn(Opcodes.ICONST_0);
                    Label olabel2 = new Label();
                    mv.visitJumpInsn(Opcodes.GOTO, olabel2);
                    mv.visitLabel(olabel1);
                    mv.visitVarInsn(Opcodes.ALOAD, 0);
                    visitFieldOrGetter(mv, classDef, field);
                    if (!BuildUtils.isArray(field.getTypeName())) {
                        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "hashCode", "()I");
                    } else {
                        mv.visitMethodInsn(INVOKESTATIC, "java/util/Arrays", "hashCode", "(" + BuildUtils.arrayType(field.getTypeName()) + ")I");
                    }
                    mv.visitLabel(olabel2);
                }
                mv.visitInsn(Opcodes.IADD);
                mv.visitVarInsn(Opcodes.ISTORE, 1);
            }
        }
        mv.visitVarInsn(Opcodes.ILOAD, 1);
        mv.visitInsn(Opcodes.IRETURN);
        Label lastLabel = null;
        if (this.debug) {
            lastLabel = new Label();
            mv.visitLabel(lastLabel);
            mv.visitLocalVariable("this", BuildUtils.getTypeDescriptor(classDef.getClassName()), null, l0, lastLabel, 0);
            mv.visitLocalVariable("hash", Type.getDescriptor(int.class), null, l0, lastLabel, 1);
        }
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }
}
Also used : FieldDefinition(org.drools.core.factmodel.FieldDefinition) Label(org.mvel2.asm.Label) MethodVisitor(org.mvel2.asm.MethodVisitor)

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