Search in sources :

Example 11 with And

use of org.mvel2.ast.And in project mvel by mvel.

the class JSRInlinerAdapter method markSubroutines.

/**
 * Walks the method and determines which internal subroutine(s), if any,
 * each instruction is a method of.
 */
private void markSubroutines() {
    BitSet anyvisited = new BitSet();
    // First walk the main subroutine and find all those instructions which
    // can be reached without invoking any JSR at all
    markSubroutineWalk(mainSubroutine, 0, anyvisited);
    // to that subroutine without following any JSR links.
    for (Iterator<Map.Entry<LabelNode, BitSet>> it = subroutineHeads.entrySet().iterator(); it.hasNext(); ) {
        Map.Entry<LabelNode, BitSet> entry = it.next();
        LabelNode lab = entry.getKey();
        BitSet sub = entry.getValue();
        int index = instructions.indexOf(lab);
        markSubroutineWalk(sub, index, anyvisited);
    }
}
Also used : LabelNode(org.mvel2.asm.tree.LabelNode) BitSet(java.util.BitSet) HashMap(java.util.HashMap) AbstractMap(java.util.AbstractMap) Map(java.util.Map)

Example 12 with And

use of org.mvel2.ast.And in project mvel by mvel.

the class JSRInlinerAdapter method markSubroutineWalk.

/**
 * Performs a depth first search walking the normal byte code path starting
 * at <code>index</code>, and adding each instruction encountered into the
 * subroutine <code>sub</code>. After this walk is complete, iterates over
 * the exception handlers to ensure that we also include those byte codes
 * which are reachable through an exception that may be thrown during the
 * execution of the subroutine. Invoked from <code>markSubroutines()</code>.
 *
 * @param sub
 *            the subroutine whose instructions must be computed.
 * @param index
 *            an instruction of this subroutine.
 * @param anyvisited
 *            indexes of the already visited instructions, i.e. marked as
 *            part of this subroutine or any previously computed subroutine.
 */
private void markSubroutineWalk(final BitSet sub, final int index, final BitSet anyvisited) {
    if (LOGGING) {
        log("markSubroutineWalk: sub=" + sub + " index=" + index);
    }
    // First find those instructions reachable via normal execution
    markSubroutineWalkDFS(sub, index, anyvisited);
    // Now, make sure we also include any applicable exception handlers
    boolean loop = true;
    while (loop) {
        loop = false;
        for (Iterator<TryCatchBlockNode> it = tryCatchBlocks.iterator(); it.hasNext(); ) {
            TryCatchBlockNode trycatch = it.next();
            if (LOGGING) {
                // TODO use of default toString().
                log("Scanning try/catch " + trycatch);
            }
            // If the handler has already been processed, skip it.
            int handlerindex = instructions.indexOf(trycatch.handler);
            if (sub.get(handlerindex)) {
                continue;
            }
            int startindex = instructions.indexOf(trycatch.start);
            int endindex = instructions.indexOf(trycatch.end);
            int nextbit = sub.nextSetBit(startindex);
            if (nextbit != -1 && nextbit < endindex) {
                if (LOGGING) {
                    log("Adding exception handler: " + startindex + '-' + endindex + " due to " + nextbit + " handler " + handlerindex);
                }
                markSubroutineWalkDFS(sub, handlerindex, anyvisited);
                loop = true;
            }
        }
    }
}
Also used : TryCatchBlockNode(org.mvel2.asm.tree.TryCatchBlockNode)

Example 13 with And

use of org.mvel2.ast.And in project mvel by mvel.

the class LocalVariablesSorter method visitFrame.

@Override
public void visitFrame(final int type, final int nLocal, final Object[] local, final int nStack, final Object[] stack) {
    if (type != Opcodes.F_NEW) {
        // uncompressed frame
        throw new IllegalStateException("ClassReader.accept() should be called with EXPAND_FRAMES flag");
    }
    // creates a copy of newLocals
    Object[] oldLocals = new Object[newLocals.length];
    System.arraycopy(newLocals, 0, oldLocals, 0, oldLocals.length);
    updateNewLocals(newLocals);
    // copies types from 'local' to 'newLocals'
    // 'newLocals' already contains the variables added with 'newLocal'
    // old local variable index
    int index = 0;
    // old local variable number
    int number = 0;
    for (; number < nLocal; ++number) {
        Object t = local[number];
        int size = t == Opcodes.LONG || t == Opcodes.DOUBLE ? 2 : 1;
        if (t != Opcodes.TOP) {
            Type typ = OBJECT_TYPE;
            if (t == Opcodes.INTEGER) {
                typ = Type.INT_TYPE;
            } else if (t == Opcodes.FLOAT) {
                typ = Type.FLOAT_TYPE;
            } else if (t == Opcodes.LONG) {
                typ = Type.LONG_TYPE;
            } else if (t == Opcodes.DOUBLE) {
                typ = Type.DOUBLE_TYPE;
            } else if (t instanceof String) {
                typ = Type.getObjectType((String) t);
            }
            setFrameLocal(remap(index, typ), t);
        }
        index += size;
    }
    // removes TOP after long and double types as well as trailing TOPs
    index = 0;
    number = 0;
    for (int i = 0; index < newLocals.length; ++i) {
        Object t = newLocals[index++];
        if (t != null && t != Opcodes.TOP) {
            newLocals[i] = t;
            number = i + 1;
            if (t == Opcodes.LONG || t == Opcodes.DOUBLE) {
                index += 1;
            }
        } else {
            newLocals[i] = Opcodes.TOP;
        }
    }
    // visits remapped frame
    mv.visitFrame(type, number, newLocals, nStack, stack);
    // restores original value of 'newLocals'
    newLocals = oldLocals;
}
Also used : Type(org.mvel2.asm.Type)

Example 14 with And

use of org.mvel2.ast.And in project mvel by mvel.

the class AbstractParser method arithmeticFunctionReduction.

/**
 * Reduce the current operations on the stack.
 *
 * @param operator the operator
 * @return a stack control code
 */
protected int arithmeticFunctionReduction(int operator) {
    ASTNode tk;
    int operator2;
    /**
     * If the next token is an operator, we check to see if it has a higher
     * precdence.
     */
    if ((tk = nextToken()) != null) {
        if (isArithmeticOperator(operator2 = tk.getOperator()) && PTABLE[operator2] > PTABLE[operator]) {
            stk.xswap();
            /**
             * The current arith. operator is of higher precedence the last.
             */
            tk = nextToken();
            /**
             * Check to see if we're compiling or executing interpretively.  If we're compiling, we really
             * need to stop if this is not a literal.
             */
            if (compileMode && !tk.isLiteral()) {
                splitAccumulator.push(tk, new OperatorNode(operator2, expr, st, pCtx));
                return OP_OVERFLOW;
            }
            dStack.push(operator = operator2, tk.getReducedValue(ctx, ctx, variableFactory));
            while (true) {
                // look ahead again
                if ((tk = nextToken()) != null && (operator2 = tk.getOperator()) != -1 && operator2 != END_OF_STMT && PTABLE[operator2] > PTABLE[operator]) {
                    if (dStack.isReduceable()) {
                        stk.copyx2(dStack);
                    }
                    /**
                     * This operator is of higher precedence, or the same level precedence.  push to the RHS.
                     */
                    dStack.push(operator = operator2, nextToken().getReducedValue(ctx, ctx, variableFactory));
                    continue;
                } else if (tk != null && operator2 != -1 && operator2 != END_OF_STMT) {
                    if (PTABLE[operator2] == PTABLE[operator]) {
                        if (!dStack.isEmpty())
                            dreduce();
                        else {
                            while (stk.isReduceable()) {
                                stk.xswap_op();
                            }
                        }
                        /**
                         * This operator is of the same level precedence.  push to the RHS.
                         */
                        dStack.push(operator = operator2, nextToken().getReducedValue(ctx, ctx, variableFactory));
                        continue;
                    } else {
                        /**
                         * The operator doesn't have higher precedence. Therfore reduce the LHS.
                         */
                        while (dStack.size() > 1) {
                            dreduce();
                        }
                        operator = tk.getOperator();
                        // Reduce the lesser or equal precedence operations.
                        while (stk.size() != 1 && stk.peek2() instanceof Integer && ((operator2 = (Integer) stk.peek2()) < PTABLE.length) && PTABLE[operator2] >= PTABLE[operator]) {
                            stk.xswap_op();
                        }
                    }
                } else {
                    if (dStack.size() > 1) {
                        dreduce();
                    }
                    if (stk.isReduceable())
                        stk.xswap();
                    break;
                }
                if ((tk = nextToken()) != null) {
                    switch(operator) {
                        case AND:
                            {
                                if (!(stk.peekBoolean()))
                                    return OP_TERMINATE;
                                else {
                                    splitAccumulator.add(tk);
                                    return AND;
                                }
                            }
                        case OR:
                            {
                                if ((stk.peekBoolean()))
                                    return OP_TERMINATE;
                                else {
                                    splitAccumulator.add(tk);
                                    return OR;
                                }
                            }
                        default:
                            stk.push(operator, tk.getReducedValue(ctx, ctx, variableFactory));
                    }
                }
            }
        } else if (!tk.isOperator()) {
            throw new CompileException("unexpected token: " + tk.getName(), expr, st);
        } else {
            reduce();
            splitAccumulator.push(tk);
        }
    }
    // keep XSWAPing and reducing, until there is nothing left.
    if (stk.isReduceable()) {
        while (true) {
            reduce();
            if (stk.isReduceable()) {
                stk.xswap();
            } else {
                break;
            }
        }
    }
    return OP_RESET_FRAME;
}
Also used : ASTNode(org.mvel2.ast.ASTNode) CompileException(org.mvel2.CompileException) OperatorNode(org.mvel2.ast.OperatorNode)

Example 15 with And

use of org.mvel2.ast.And in project mvel by mvel.

the class AbstractParser method procTypedNode.

/**
 * Process the current typed node
 *
 * @param decl node is a declaration or not
 * @return and ast node
 */
private ASTNode procTypedNode(boolean decl) {
    while (true) {
        if (lastNode.getLiteralValue() instanceof String) {
            char[] tmp = ((String) lastNode.getLiteralValue()).toCharArray();
            TypeDescriptor tDescr = new TypeDescriptor(tmp, 0, tmp.length, 0);
            try {
                lastNode.setLiteralValue(getClassReference(pCtx, tDescr));
                lastNode.discard();
            } catch (Exception e) {
            // fall through;
            }
        }
        if (lastNode.isLiteral() && lastNode.getLiteralValue() instanceof Class) {
            lastNode.discard();
            captureToEOS();
            if (decl) {
                splitAccumulator.add(new DeclTypedVarNode(new String(expr, st, cursor - st), expr, st, cursor - st, (Class) lastNode.getLiteralValue(), fields | ASTNode.ASSIGN, pCtx));
            } else {
                captureToEOS();
                splitAccumulator.add(new TypedVarNode(expr, st, cursor - st - 1, fields | ASTNode.ASSIGN, (Class) lastNode.getLiteralValue(), pCtx));
            }
        } else if (lastNode instanceof Proto) {
            captureToEOS();
            if (decl) {
                splitAccumulator.add(new DeclProtoVarNode(new String(expr, st, cursor - st), (Proto) lastNode, fields | ASTNode.ASSIGN, pCtx));
            } else {
                splitAccumulator.add(new ProtoVarNode(expr, st, cursor - st, fields | ASTNode.ASSIGN, (Proto) lastNode, pCtx));
            }
        } else // this redundant looking code is needed to work with the interpreter and MVELSH properly.
        if ((fields & ASTNode.COMPILE_IMMEDIATE) == 0) {
            if (stk.peek() instanceof Class) {
                captureToEOS();
                if (decl) {
                    splitAccumulator.add(new DeclTypedVarNode(new String(expr, st, cursor - st), expr, st, cursor - st, (Class) stk.pop(), fields | ASTNode.ASSIGN, pCtx));
                } else {
                    splitAccumulator.add(new TypedVarNode(expr, st, cursor - st, fields | ASTNode.ASSIGN, (Class) stk.pop(), pCtx));
                }
            } else if (stk.peek() instanceof Proto) {
                captureToEOS();
                if (decl) {
                    splitAccumulator.add(new DeclProtoVarNode(new String(expr, st, cursor - st), (Proto) stk.pop(), fields | ASTNode.ASSIGN, pCtx));
                } else {
                    splitAccumulator.add(new ProtoVarNode(expr, st, cursor - st, fields | ASTNode.ASSIGN, (Proto) stk.pop(), pCtx));
                }
            } else {
                throw new CompileException("unknown class or illegal statement: " + lastNode.getLiteralValue(), expr, cursor);
            }
        } else {
            throw new CompileException("unknown class or illegal statement: " + lastNode.getLiteralValue(), expr, cursor);
        }
        skipWhitespace();
        if (cursor < end && expr[cursor] == ',') {
            st = ++cursor;
            splitAccumulator.add(new EndOfStatement(pCtx));
        } else {
            return (ASTNode) splitAccumulator.pop();
        }
    }
}
Also used : ProtoVarNode(org.mvel2.ast.ProtoVarNode) DeclProtoVarNode(org.mvel2.ast.DeclProtoVarNode) EndOfStatement(org.mvel2.ast.EndOfStatement) CompileException(org.mvel2.CompileException) RedundantCodeException(org.mvel2.ast.RedundantCodeException) TypeDescriptor(org.mvel2.ast.TypeDescriptor) Proto(org.mvel2.ast.Proto) DeclProtoVarNode(org.mvel2.ast.DeclProtoVarNode) IndexedDeclTypedVarNode(org.mvel2.ast.IndexedDeclTypedVarNode) DeclTypedVarNode(org.mvel2.ast.DeclTypedVarNode) ASTNode(org.mvel2.ast.ASTNode) CompileException(org.mvel2.CompileException) IndexedDeclTypedVarNode(org.mvel2.ast.IndexedDeclTypedVarNode) TypedVarNode(org.mvel2.ast.TypedVarNode) DeclTypedVarNode(org.mvel2.ast.DeclTypedVarNode)

Aggregations

CompileException (org.mvel2.CompileException)22 HashMap (java.util.HashMap)13 Map (java.util.Map)12 ParserContext (org.mvel2.ParserContext)12 ASTNode (org.mvel2.ast.ASTNode)9 Type (org.mvel2.asm.Type)8 Serializable (java.io.Serializable)7 Method (java.lang.reflect.Method)7 ExecutableStatement (org.mvel2.compiler.ExecutableStatement)7 ExpressionCompiler (org.mvel2.compiler.ExpressionCompiler)7 StringAppender (org.mvel2.util.StringAppender)6 EndOfStatement (org.mvel2.ast.EndOfStatement)5 IOException (java.io.IOException)4 BitSet (java.util.BitSet)4 List (java.util.List)4 LabelNode (org.mvel2.asm.tree.LabelNode)4 LiteralNode (org.mvel2.ast.LiteralNode)4 Proto (org.mvel2.ast.Proto)4 ArrayList (java.util.ArrayList)3 Money (org.broadleafcommerce.common.money.Money)3