Search in sources :

Example 16 with Label

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

the class AbstractProxyClassBuilderImpl method fixPrimitive.

private void fixPrimitive(MethodVisitor mv, FieldDefinition coreField, int j) {
    if (BuildUtils.isPrimitive(coreField.getTypeName())) {
        Label l0 = new Label();
        mv.visitJumpInsn(IFNULL, l0);
        mv.visitVarInsn(ALOAD, j);
        mv.visitTypeInsn(CHECKCAST, BuildUtils.getInternalType(BuildUtils.box(coreField.getTypeName())));
        mv.visitMethodInsn(INVOKEVIRTUAL, BuildUtils.getInternalType(BuildUtils.box(coreField.getTypeName())), BuildUtils.numericMorph(BuildUtils.box(coreField.getTypeName())), Type.getMethodDescriptor(Type.getType(coreField.getType())), false);
        Label l1 = new Label();
        mv.visitJumpInsn(GOTO, l1);
        mv.visitLabel(l0);
        mv.visitInsn(BuildUtils.zero(coreField.getTypeName()));
        mv.visitLabel(l1);
    } else {
        mv.visitTypeInsn(CHECKCAST, Type.getInternalName(coreField.getType()));
    }
}
Also used : Label(org.mvel2.asm.Label)

Example 17 with Label

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

the class AbstractProxyClassBuilderImpl method synchField.

protected void synchField(MethodVisitor mv, FieldDefinition fld, String proxyName) {
    mv.visitVarInsn(ALOAD, 0);
    mv.visitMethodInsn(INVOKEVIRTUAL, BuildUtils.getInternalType(proxyName), BuildUtils.getterName(fld.getName(), fld.getTypeName()), "()" + BuildUtils.getTypeDescriptor(fld.getTypeName()), false);
    Label l0 = null;
    if (!BuildUtils.isPrimitive(fld.getTypeName())) {
        l0 = new Label();
        mv.visitJumpInsn(IFNONNULL, l0);
    }
    mv.visitVarInsn(ALOAD, 0);
    mv.visitLdcInsn(fld.getInitExpr());
    if (BuildUtils.isPrimitive(fld.getTypeName())) {
        mv.visitFieldInsn(GETSTATIC, BuildUtils.getInternalType(BuildUtils.box(fld.getTypeName())), "TYPE", Type.getDescriptor(Class.class));
    } else {
        mv.visitLdcInsn(Type.getType(BuildUtils.getTypeDescriptor(fld.getTypeName())));
    }
    mv.visitMethodInsn(INVOKESTATIC, Type.getInternalName(MVEL.class), "eval", Type.getMethodDescriptor(Type.getType(Object.class), Type.getType(String.class), Type.getType(Class.class)), false);
    if (BuildUtils.isPrimitive(fld.getTypeName())) {
        mv.visitTypeInsn(CHECKCAST, BuildUtils.getInternalType(BuildUtils.box(fld.getTypeName())));
        mv.visitMethodInsn(INVOKEVIRTUAL, BuildUtils.getInternalType(BuildUtils.box(fld.getTypeName())), BuildUtils.numericMorph(BuildUtils.box(fld.getTypeName())), "()" + BuildUtils.getTypeDescriptor(fld.getTypeName()), false);
    } else {
        mv.visitTypeInsn(CHECKCAST, BuildUtils.getInternalType(fld.getTypeName()));
    }
    mv.visitMethodInsn(INVOKEVIRTUAL, BuildUtils.getInternalType(proxyName), BuildUtils.setterName(fld.getName(), fld.getTypeName()), "(" + BuildUtils.getTypeDescriptor(fld.getTypeName()) + ")" + Type.getDescriptor(void.class), false);
    if (!BuildUtils.isPrimitive(fld.getTypeName())) {
        mv.visitLabel(l0);
    }
}
Also used : MVEL(org.mvel2.MVEL) Label(org.mvel2.asm.Label)

Example 18 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, WorkingMemory.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, WorkingMemory.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, WorkingMemory.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 : ClassGenerator(org.drools.core.rule.builder.dialect.asm.ClassGenerator) PredicateStub(org.drools.core.rule.builder.dialect.asm.PredicateStub) 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 19 with Label

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

the class ASMReturnValueStubBuilder method createStubReturnValue.

private void createStubReturnValue(final ClassGenerator generator, final InvokerDataProvider data, final Map vars) {
    generator.setInterfaces(ReturnValueStub.class, CompiledInvoker.class).addField(ACC_PRIVATE + ACC_VOLATILE, "returnValue", ReturnValueExpression.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, "replaceDeclaration", generator.methodDescr(null, Declaration.class, Declaration.class)).addMethod(ACC_PUBLIC, "evaluate", generator.methodDescr(FieldValue.class, Object.class, Tuple.class, Declaration[].class, Declaration[].class, WorkingMemory.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("returnValue", ReturnValueExpression.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("returnValue", ReturnValueExpression.class);
            // if (returnValue == 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);
            invokeStatic(ReturnValueGenerator.class, "generate", null, ReturnValueStub.class, Tuple.class, Declaration[].class, Declaration[].class, WorkingMemory.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("returnValue", ReturnValueExpression.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(ReturnValueExpression.class, "evaluate", FieldValue.class, Object.class, Tuple.class, Declaration[].class, Declaration[].class, WorkingMemory.class, Object.class);
            mv.visitInsn(ARETURN);
        }
    }).addMethod(ACC_PUBLIC, "setReturnValue", generator.methodDescr(null, ReturnValueExpression.class), new ClassGenerator.MethodBody() {

        public void body(MethodVisitor mv) {
            putFieldInThisFromRegistry("returnValue", ReturnValueExpression.class, 1);
            mv.visitInsn(RETURN);
        }
    });
}
Also used : ReturnValueExpression(org.drools.core.spi.ReturnValueExpression) ClassGenerator(org.drools.core.rule.builder.dialect.asm.ClassGenerator) ReturnValueStub(org.drools.core.rule.builder.dialect.asm.ReturnValueStub) Label(org.mvel2.asm.Label) Declaration(org.drools.core.rule.Declaration) CompiledInvoker(org.drools.core.spi.CompiledInvoker) MethodVisitor(org.mvel2.asm.MethodVisitor)

Example 20 with Label

use of org.mvel2.asm.Label in project mvel by mvel.

the class Analyzer method analyze.

/**
 * Analyzes the given method.
 *
 * @param owner
 *            the internal name of the class to which the method belongs.
 * @param m
 *            the method to be analyzed.
 * @return the symbolic state of the execution stack frame at each bytecode
 *         instruction of the method. The size of the returned array is
 *         equal to the number of instructions (and labels) of the method. A
 *         given frame is <tt>null</tt> if and only if the corresponding
 *         instruction cannot be reached (dead code).
 * @throws AnalyzerException
 *             if a problem occurs during the analysis.
 */
@SuppressWarnings("unchecked")
public Frame<V>[] analyze(final String owner, final MethodNode m) throws AnalyzerException {
    if ((m.access & (ACC_ABSTRACT | ACC_NATIVE)) != 0) {
        frames = (Frame<V>[]) new Frame<?>[0];
        return frames;
    }
    n = m.instructions.size();
    insns = m.instructions;
    handlers = (List<TryCatchBlockNode>[]) new List<?>[n];
    frames = (Frame<V>[]) new Frame<?>[n];
    subroutines = new Subroutine[n];
    queued = new boolean[n];
    queue = new int[n];
    top = 0;
    // computes exception handlers for each instruction
    for (int i = 0; i < m.tryCatchBlocks.size(); ++i) {
        TryCatchBlockNode tcb = m.tryCatchBlocks.get(i);
        int begin = insns.indexOf(tcb.start);
        int end = insns.indexOf(tcb.end);
        for (int j = begin; j < end; ++j) {
            List<TryCatchBlockNode> insnHandlers = handlers[j];
            if (insnHandlers == null) {
                insnHandlers = new ArrayList<TryCatchBlockNode>();
                handlers[j] = insnHandlers;
            }
            insnHandlers.add(tcb);
        }
    }
    // computes the subroutine for each instruction:
    Subroutine main = new Subroutine(null, m.maxLocals, null);
    List<AbstractInsnNode> subroutineCalls = new ArrayList<AbstractInsnNode>();
    Map<LabelNode, Subroutine> subroutineHeads = new HashMap<LabelNode, Subroutine>();
    findSubroutine(0, main, subroutineCalls);
    while (!subroutineCalls.isEmpty()) {
        JumpInsnNode jsr = (JumpInsnNode) subroutineCalls.remove(0);
        Subroutine sub = subroutineHeads.get(jsr.label);
        if (sub == null) {
            sub = new Subroutine(jsr.label, m.maxLocals, jsr);
            subroutineHeads.put(jsr.label, sub);
            findSubroutine(insns.indexOf(jsr.label), sub, subroutineCalls);
        } else {
            sub.callers.add(jsr);
        }
    }
    for (int i = 0; i < n; ++i) {
        if (subroutines[i] != null && subroutines[i].start == null) {
            subroutines[i] = null;
        }
    }
    // initializes the data structures for the control flow analysis
    Frame<V> current = newFrame(m.maxLocals, m.maxStack);
    Frame<V> handler = newFrame(m.maxLocals, m.maxStack);
    current.setReturn(interpreter.newValue(Type.getReturnType(m.desc)));
    Type[] args = Type.getArgumentTypes(m.desc);
    int local = 0;
    if ((m.access & ACC_STATIC) == 0) {
        Type ctype = Type.getObjectType(owner);
        current.setLocal(local++, interpreter.newValue(ctype));
    }
    for (int i = 0; i < args.length; ++i) {
        current.setLocal(local++, interpreter.newValue(args[i]));
        if (args[i].getSize() == 2) {
            current.setLocal(local++, interpreter.newValue(null));
        }
    }
    while (local < m.maxLocals) {
        current.setLocal(local++, interpreter.newValue(null));
    }
    merge(0, current, null);
    init(owner, m);
    // control flow analysis
    while (top > 0) {
        int insn = queue[--top];
        Frame<V> f = frames[insn];
        Subroutine subroutine = subroutines[insn];
        queued[insn] = false;
        AbstractInsnNode insnNode = null;
        try {
            insnNode = m.instructions.get(insn);
            int insnOpcode = insnNode.getOpcode();
            int insnType = insnNode.getType();
            if (insnType == AbstractInsnNode.LABEL || insnType == AbstractInsnNode.LINE || insnType == AbstractInsnNode.FRAME) {
                merge(insn + 1, f, subroutine);
                newControlFlowEdge(insn, insn + 1);
            } else {
                current.init(f).execute(insnNode, interpreter);
                subroutine = subroutine == null ? null : subroutine.copy();
                if (insnNode instanceof JumpInsnNode) {
                    JumpInsnNode j = (JumpInsnNode) insnNode;
                    if (insnOpcode != GOTO && insnOpcode != JSR) {
                        merge(insn + 1, current, subroutine);
                        newControlFlowEdge(insn, insn + 1);
                    }
                    int jump = insns.indexOf(j.label);
                    if (insnOpcode == JSR) {
                        merge(jump, current, new Subroutine(j.label, m.maxLocals, j));
                    } else {
                        merge(jump, current, subroutine);
                    }
                    newControlFlowEdge(insn, jump);
                } else if (insnNode instanceof LookupSwitchInsnNode) {
                    LookupSwitchInsnNode lsi = (LookupSwitchInsnNode) insnNode;
                    int jump = insns.indexOf(lsi.dflt);
                    merge(jump, current, subroutine);
                    newControlFlowEdge(insn, jump);
                    for (int j = 0; j < lsi.labels.size(); ++j) {
                        LabelNode label = lsi.labels.get(j);
                        jump = insns.indexOf(label);
                        merge(jump, current, subroutine);
                        newControlFlowEdge(insn, jump);
                    }
                } else if (insnNode instanceof TableSwitchInsnNode) {
                    TableSwitchInsnNode tsi = (TableSwitchInsnNode) insnNode;
                    int jump = insns.indexOf(tsi.dflt);
                    merge(jump, current, subroutine);
                    newControlFlowEdge(insn, jump);
                    for (int j = 0; j < tsi.labels.size(); ++j) {
                        LabelNode label = tsi.labels.get(j);
                        jump = insns.indexOf(label);
                        merge(jump, current, subroutine);
                        newControlFlowEdge(insn, jump);
                    }
                } else if (insnOpcode == RET) {
                    if (subroutine == null) {
                        throw new AnalyzerException(insnNode, "RET instruction outside of a sub routine");
                    }
                    for (int i = 0; i < subroutine.callers.size(); ++i) {
                        JumpInsnNode caller = subroutine.callers.get(i);
                        int call = insns.indexOf(caller);
                        if (frames[call] != null) {
                            merge(call + 1, frames[call], current, subroutines[call], subroutine.access);
                            newControlFlowEdge(insn, call + 1);
                        }
                    }
                } else if (insnOpcode != ATHROW && (insnOpcode < IRETURN || insnOpcode > RETURN)) {
                    if (subroutine != null) {
                        if (insnNode instanceof VarInsnNode) {
                            int var = ((VarInsnNode) insnNode).var;
                            subroutine.access[var] = true;
                            if (insnOpcode == LLOAD || insnOpcode == DLOAD || insnOpcode == LSTORE || insnOpcode == DSTORE) {
                                subroutine.access[var + 1] = true;
                            }
                        } else if (insnNode instanceof IincInsnNode) {
                            int var = ((IincInsnNode) insnNode).var;
                            subroutine.access[var] = true;
                        }
                    }
                    merge(insn + 1, current, subroutine);
                    newControlFlowEdge(insn, insn + 1);
                }
            }
            List<TryCatchBlockNode> insnHandlers = handlers[insn];
            if (insnHandlers != null) {
                for (int i = 0; i < insnHandlers.size(); ++i) {
                    TryCatchBlockNode tcb = insnHandlers.get(i);
                    Type type;
                    if (tcb.type == null) {
                        type = Type.getObjectType("java/lang/Throwable");
                    } else {
                        type = Type.getObjectType(tcb.type);
                    }
                    int jump = insns.indexOf(tcb.handler);
                    if (newControlFlowExceptionEdge(insn, tcb)) {
                        handler.init(f);
                        handler.clearStack();
                        handler.push(interpreter.newValue(type));
                        merge(jump, handler, subroutine);
                    }
                }
            }
        } catch (AnalyzerException e) {
            throw new AnalyzerException(e.node, "Error at instruction " + insn + ": " + e.getMessage(), e);
        } catch (Exception e) {
            throw new AnalyzerException(insnNode, "Error at instruction " + insn + ": " + e.getMessage(), e);
        }
    }
    return frames;
}
Also used : LabelNode(org.mvel2.asm.tree.LabelNode) TryCatchBlockNode(org.mvel2.asm.tree.TryCatchBlockNode) TableSwitchInsnNode(org.mvel2.asm.tree.TableSwitchInsnNode) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) AbstractInsnNode(org.mvel2.asm.tree.AbstractInsnNode) Type(org.mvel2.asm.Type) JumpInsnNode(org.mvel2.asm.tree.JumpInsnNode) IincInsnNode(org.mvel2.asm.tree.IincInsnNode) ArrayList(java.util.ArrayList) List(java.util.List) InsnList(org.mvel2.asm.tree.InsnList) LookupSwitchInsnNode(org.mvel2.asm.tree.LookupSwitchInsnNode) VarInsnNode(org.mvel2.asm.tree.VarInsnNode)

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