Search in sources :

Example 1 with OnFinally

use of lucee.transformer.bytecode.visitor.OnFinally in project Lucee by lucee.

the class TryCatchFinally method _writeOut.

/**
 * @see lucee.transformer.bytecode.statement.StatementBase#_writeOut(org.objectweb.asm.commons.GeneratorAdapter)
 */
@Override
public void _writeOut(BytecodeContext bc) throws TransformerException {
    final GeneratorAdapter adapter = bc.getAdapter();
    adapter.visitLabel(begin);
    // Reference ref=null;
    final int lRef = adapter.newLocal(Types.REFERENCE);
    adapter.visitInsn(Opcodes.ACONST_NULL);
    adapter.storeLocal(lRef);
    // has no try body, if there is no try body, no catches are executed, only finally
    if (!tryBody.hasStatements()) {
        if (finallyBody != null)
            finallyBody.writeOut(bc);
        return;
    }
    // PageExceptionImpl old=pc.getCatch();
    final int old = adapter.newLocal(Types.PAGE_EXCEPTION);
    adapter.loadArg(0);
    adapter.invokeVirtual(Types.PAGE_CONTEXT, TagTry.GET_CATCH);
    adapter.storeLocal(old);
    TryCatchFinallyVisitor tcfv = new TryCatchFinallyVisitor(new OnFinally() {

        @Override
        public void _writeOut(BytecodeContext bc) throws TransformerException {
            adapter.loadArg(0);
            adapter.loadLocal(old);
            adapter.invokeVirtual(Types.PAGE_CONTEXT, TagTry.SET_CATCH_PE);
            _writeOutFinally(bc, lRef);
        }
    }, getFlowControlFinal());
    // try
    tcfv.visitTryBegin(bc);
    tryBody.writeOut(bc);
    int lThrow = tcfv.visitTryEndCatchBeging(bc);
    _writeOutCatch(bc, lRef, lThrow, old);
    tcfv.visitCatchEnd(bc);
}
Also used : OnFinally(lucee.transformer.bytecode.visitor.OnFinally) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) TryCatchFinallyVisitor(lucee.transformer.bytecode.visitor.TryCatchFinallyVisitor) TransformerException(lucee.transformer.TransformerException) BytecodeContext(lucee.transformer.bytecode.BytecodeContext)

Example 2 with OnFinally

use of lucee.transformer.bytecode.visitor.OnFinally in project Lucee by lucee.

the class TagGroupUtil method writeOutTypeQuery.

public static void writeOutTypeQuery(final TagGroup tag, BytecodeContext bc) throws TransformerException {
    final GeneratorAdapter adapter = bc.getAdapter();
    tag.setNumberIterator(adapter.newLocal(NUMBER_ITERATOR));
    boolean isOutput = tag.getType() == TagGroup.TAG_OUTPUT;
    ParseBodyVisitor pbv = isOutput ? new ParseBodyVisitor() : null;
    if (isOutput)
        pbv.visitBegin(bc);
    // Query query=pc.getQuery(@query);
    tag.setQuery(adapter.newLocal(Types.QUERY));
    adapter.loadArg(0);
    Expression val = tag.getAttribute("query").getValue();
    val.writeOut(bc, Expression.MODE_REF);
    if (val instanceof LitString)
        adapter.invokeVirtual(Types.PAGE_CONTEXT, TagLoop.GET_QUERY_STRING);
    else
        adapter.invokeVirtual(Types.PAGE_CONTEXT, TagLoop.GET_QUERY_OBJ);
    adapter.storeLocal(tag.getQuery());
    tag.setPID(adapter.newLocal(Types.INT_VALUE));
    adapter.loadArg(0);
    adapter.invokeVirtual(Types.PAGE_CONTEXT, TagLoop.GET_ID);
    adapter.storeLocal(tag.getPID());
    // int startAt=query.getCurrentrow();
    final int startAt = adapter.newLocal(Types.INT_VALUE);
    adapter.loadLocal(tag.getQuery());
    adapter.loadLocal(tag.getPID());
    // adapter.loadArg(0);
    // adapter.invokeVirtual(Types.PAGE_CONTEXT, TagLoop.GET_ID);
    adapter.invokeInterface(Types.QUERY, TagLoop.GET_CURRENTROW_1);
    adapter.storeLocal(startAt);
    // if(query.getRecordcount()>0) {
    DecisionIntVisitor div = new DecisionIntVisitor();
    div.visitBegin();
    adapter.loadLocal(tag.getQuery());
    adapter.invokeInterface(Types.QUERY, GET_RECORDCOUNT);
    div.visitGT();
    adapter.push(0);
    div.visitEnd(bc);
    Label ifRecCount = new Label();
    adapter.ifZCmp(Opcodes.IFEQ, ifRecCount);
    // startrow
    int from = adapter.newLocal(Types.INT_VALUE);
    Attribute attrStartRow = tag.getAttribute("startrow");
    if (attrStartRow != null) {
        // NumberRange.range(@startrow,1)
        // attrStartRow.getValue().writeOut(bc, Expression.MODE_VALUE);
        bc.getFactory().toExprInt(attrStartRow.getValue()).writeOut(bc, Expression.MODE_VALUE);
        // adapter.visitInsn(Opcodes.D2I);
        adapter.push(1);
        adapter.invokeStatic(Types.NUMBER_RANGE, RANGE);
    // adapter.visitInsn(Opcodes.D2I);
    } else {
        adapter.push(1);
    }
    adapter.storeLocal(from);
    // numberIterator
    adapter.loadLocal(from);
    adapter.loadLocal(tag.getQuery());
    adapter.invokeInterface(Types.QUERY, GET_RECORDCOUNT);
    // adapter.visitInsn(Opcodes.I2D);
    Attribute attrMaxRow = tag.getAttribute("maxrows");
    Attribute attrEndRow = tag.getAttribute("endrow");
    if (attrMaxRow != null) {
        bc.getFactory().toExprInt(attrMaxRow.getValue()).writeOut(bc, Expression.MODE_VALUE);
        adapter.invokeStatic(NUMBER_ITERATOR, LOAD_MAX);
    } else if (attrEndRow != null) {
        bc.getFactory().toExprInt(attrEndRow.getValue()).writeOut(bc, Expression.MODE_VALUE);
        adapter.invokeStatic(NUMBER_ITERATOR, LOAD_END);
    } else {
        adapter.invokeStatic(NUMBER_ITERATOR, LOAD_2);
    }
    adapter.storeLocal(tag.getNumberIterator());
    // Group
    Attribute attrGroup = tag.getAttribute("group");
    Attribute attrGroupCS = tag.getAttribute("groupcasesensitive");
    tag.setGroup(adapter.newLocal(Types.STRING));
    final int groupCaseSensitive = adapter.newLocal(Types.BOOLEAN_VALUE);
    if (attrGroup != null) {
        attrGroup.getValue().writeOut(bc, Expression.MODE_REF);
        adapter.storeLocal(tag.getGroup());
        if (attrGroupCS != null)
            attrGroupCS.getValue().writeOut(bc, Expression.MODE_VALUE);
        else
            adapter.push(false);
        adapter.storeLocal(groupCaseSensitive);
    }
    // pc.us().addQuery(query);
    adapter.loadArg(0);
    adapter.invokeVirtual(Types.PAGE_CONTEXT, US);
    adapter.loadLocal(tag.getQuery());
    adapter.invokeInterface(UNDEFINED, ADD_QUERY);
    // current
    final int current = adapter.newLocal(Types.INT_VALUE);
    adapter.loadLocal(from);
    adapter.push(1);
    adapter.visitInsn(Opcodes.ISUB);
    adapter.storeLocal(current);
    // Try
    TryFinallyVisitor tfv = new TryFinallyVisitor(new OnFinally() {

        @Override
        public void _writeOut(BytecodeContext bc) {
            // query.reset();
            // query.go(startAt);
            adapter.loadLocal(tag.getQuery());
            adapter.loadLocal(startAt);
            adapter.loadLocal(tag.getPID());
            // adapter.loadArg(0);
            // adapter.invokeVirtual(Types.PAGE_CONTEXT, TagLoop.GET_ID);
            adapter.invokeInterface(Types.QUERY, TagLoop.GO);
            adapter.pop();
            // pc.us().removeQuery();
            adapter.loadArg(0);
            adapter.invokeVirtual(Types.PAGE_CONTEXT, US);
            adapter.invokeInterface(UNDEFINED, REMOVE_QUERY);
            // NumberIterator.release(ni);
            adapter.loadLocal(tag.getNumberIterator());
            adapter.invokeStatic(NUMBER_ITERATOR, REALEASE);
        }
    }, null);
    tfv.visitTryBegin(bc);
    WhileVisitor wv = new WhileVisitor();
    if (tag instanceof TagLoop)
        ((TagLoop) tag).setLoopVisitor(wv);
    wv.visitBeforeExpression(bc);
    // while(ni.isValid()) {
    adapter.loadLocal(tag.getNumberIterator());
    adapter.loadLocal(current);
    adapter.push(1);
    adapter.visitInsn(Opcodes.IADD);
    adapter.invokeVirtual(NUMBER_ITERATOR, IS_VALID_1);
    wv.visitAfterExpressionBeforeBody(bc);
    // if(!query.go(ni.current()))break;
    adapter.loadLocal(tag.getQuery());
    adapter.loadLocal(tag.getNumberIterator());
    adapter.invokeVirtual(NUMBER_ITERATOR, CURRENT);
    adapter.loadLocal(tag.getPID());
    adapter.invokeInterface(Types.QUERY, TagLoop.GO);
    NotVisitor.visitNot(bc);
    Label _if = new Label();
    adapter.ifZCmp(Opcodes.IFEQ, _if);
    wv.visitBreak(bc);
    adapter.visitLabel(_if);
    if (attrGroup != null) {
        // NumberIterator oldNi=numberIterator;
        int oldNi = adapter.newLocal(NUMBER_ITERATOR);
        adapter.loadLocal(tag.getNumberIterator());
        adapter.storeLocal(oldNi);
        // numberIterator=NumberIterator.load(ni,query,group,grp_case);
        adapter.loadArg(0);
        adapter.loadLocal(tag.getNumberIterator());
        adapter.loadLocal(tag.getQuery());
        adapter.loadLocal(tag.getGroup());
        adapter.loadLocal(groupCaseSensitive);
        adapter.invokeStatic(NUMBER_ITERATOR, LOAD_5);
        adapter.storeLocal(tag.getNumberIterator());
        // current=oldNi.current();
        adapter.loadLocal(oldNi);
        adapter.invokeVirtual(NUMBER_ITERATOR, CURRENT);
        adapter.storeLocal(current);
        tag.getBody().writeOut(bc);
        // tmp(adapter,current);
        // NumberIterator.release(ni);
        adapter.loadLocal(tag.getNumberIterator());
        adapter.invokeStatic(NUMBER_ITERATOR, REALEASE);
        // numberIterator=oldNi;
        adapter.loadLocal(oldNi);
        adapter.storeLocal(tag.getNumberIterator());
    } else {
        // current=ni.current();
        adapter.loadLocal(tag.getNumberIterator());
        adapter.invokeVirtual(NUMBER_ITERATOR, CURRENT);
        adapter.storeLocal(current);
        tag.getBody().writeOut(bc);
    }
    // ni.setCurrent(current+1);
    /*adapter.loadLocal(tag.getNumberIterator());
					adapter.loadLocal(current);
					adapter.push(1);
					adapter.visitInsn(Opcodes.IADD);
					adapter.invokeVirtual(NUMBER_ITERATOR, SET_CURRENT);*/
    wv.visitAfterBody(bc, tag.getEnd());
    tfv.visitTryEnd(bc);
    adapter.visitLabel(ifRecCount);
    if (isOutput)
        pbv.visitEnd(bc);
}
Also used : ParseBodyVisitor(lucee.transformer.bytecode.visitor.ParseBodyVisitor) Label(org.objectweb.asm.Label) LitString(lucee.transformer.expression.literal.LitString) Expression(lucee.transformer.expression.Expression) OnFinally(lucee.transformer.bytecode.visitor.OnFinally) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) DecisionIntVisitor(lucee.transformer.bytecode.visitor.DecisionIntVisitor) WhileVisitor(lucee.transformer.bytecode.visitor.WhileVisitor) TryFinallyVisitor(lucee.transformer.bytecode.visitor.TryFinallyVisitor) BytecodeContext(lucee.transformer.bytecode.BytecodeContext)

Example 3 with OnFinally

use of lucee.transformer.bytecode.visitor.OnFinally in project Lucee by lucee.

the class TagHelper method writeOut.

/**
 * writes out the tag
 * @param tag
 * @param bc
 * @param doReuse
 * @throws TransformerException
 * @throws BundleException
 * @throws ClassException
 */
public static void writeOut(Tag tag, BytecodeContext bc, boolean doReuse, final FlowControlFinal fcf) throws TransformerException {
    final GeneratorAdapter adapter = bc.getAdapter();
    final TagLibTag tlt = tag.getTagLibTag();
    final ClassDefinition cd = tlt.getTagClassDefinition();
    final boolean fromBundle = cd.getName() != null;
    final Type currType;
    if (fromBundle) {
        try {
            if (Reflector.isInstaneOf(cd.getClazz(), BodyTag.class))
                currType = BODY_TAG;
            else
                currType = TAG;
        } catch (Exception e) {
            if (e instanceof TransformerException)
                throw (TransformerException) e;
            throw new TransformerException(e, tag.getStart());
        }
    } else
        currType = getTagType(tag);
    final int currLocal = adapter.newLocal(currType);
    Label tagBegin = new Label();
    Label tagEnd = new Label();
    ExpressionUtil.visitLine(bc, tag.getStart());
    // TODO adapter.visitLocalVariable("tag", "L"+currType.getInternalName()+";", null, tagBegin, tagEnd, currLocal);
    adapter.visitLabel(tagBegin);
    // tag=pc.use(String tagClassName,String tagBundleName, String tagBundleVersion, String fullname,int attrType) throws PageException {
    adapter.loadArg(0);
    adapter.checkCast(Types.PAGE_CONTEXT_IMPL);
    adapter.push(cd.getClassName());
    // has bundle info/version
    if (fromBundle) {
        // name
        adapter.push(cd.getName());
        // version
        if (cd.getVersion() != null)
            adapter.push(cd.getVersionAsString());
        else
            ASMConstants.NULL(adapter);
    }
    adapter.push(tlt.getFullName());
    adapter.push(tlt.getAttributeType());
    adapter.invokeVirtual(Types.PAGE_CONTEXT_IMPL, fromBundle ? USE5 : USE3);
    if (currType != TAG)
        adapter.checkCast(currType);
    adapter.storeLocal(currLocal);
    TryFinallyVisitor outerTcfv = new TryFinallyVisitor(new OnFinally() {

        @Override
        public void _writeOut(BytecodeContext bc) {
            adapter.loadArg(0);
            adapter.checkCast(Types.PAGE_CONTEXT_IMPL);
            adapter.loadLocal(currLocal);
            if (cd.getName() != null) {
                adapter.push(cd.getName());
                if (cd.getVersion() != null)
                    adapter.push(cd.getVersionAsString());
                else
                    ASMConstants.NULL(adapter);
            }
            adapter.invokeVirtual(Types.PAGE_CONTEXT_IMPL, fromBundle ? RE_USE3 : RE_USE1);
        }
    }, null);
    if (doReuse)
        outerTcfv.visitTryBegin(bc);
    // appendix
    if (tlt.hasAppendix()) {
        adapter.loadLocal(currLocal);
        adapter.push(tag.getAppendix());
        if (// PageContextUtil.setAppendix(tag,appendix)
        fromBundle)
            ASMUtil.invoke(ASMUtil.STATIC, adapter, Types.TAG_UTIL, SET_APPENDIX2);
        else
            // tag.setAppendix(appendix)
            ASMUtil.invoke(ASMUtil.VIRTUAL, adapter, currType, SET_APPENDIX1);
    }
    // hasBody
    boolean hasBody = tag.getBody() != null;
    if (tlt.isBodyFree() && tlt.hasBodyMethodExists()) {
        adapter.loadLocal(currLocal);
        adapter.push(hasBody);
        if (// PageContextUtil.setAppendix(tag,appendix)
        fromBundle)
            ASMUtil.invoke(ASMUtil.STATIC, adapter, Types.TAG_UTIL, HAS_BODY2);
        else
            // tag.setAppendix(appendix)
            ASMUtil.invoke(ASMUtil.VIRTUAL, adapter, currType, HAS_BODY1);
    }
    // default attributes (get overwritten by attributeCollection because of that set before)
    setAttributes(bc, tag, currLocal, currType, true, fromBundle);
    // attributeCollection
    Attribute attrColl = tag.getAttribute("attributecollection");
    if (attrColl != null) {
        int attrType = tag.getTagLibTag().getAttributeType();
        if (TagLibTag.ATTRIBUTE_TYPE_NONAME != attrType) {
            tag.removeAttribute("attributecollection");
            // TagUtil.setAttributeCollection(Tag, Struct)
            adapter.loadArg(0);
            adapter.loadLocal(currLocal);
            if (currType != TAG)
                adapter.cast(currType, TAG);
            // /
            TagLibTagAttr[] missings = tag.getMissingAttributes();
            if (!ArrayUtil.isEmpty(missings)) {
                ArrayVisitor av = new ArrayVisitor();
                av.visitBegin(adapter, MISSING_ATTRIBUTE, missings.length);
                int count = 0;
                TagLibTagAttr miss;
                for (int i = 0; i < missings.length; i++) {
                    miss = missings[i];
                    av.visitBeginItem(adapter, count++);
                    bc.getFactory().registerKey(bc, bc.getFactory().createLitString(miss.getName()), false);
                    adapter.push(miss.getType());
                    if (ArrayUtil.isEmpty(miss.getAlias()))
                        adapter.invokeStatic(MISSING_ATTRIBUTE, NEW_INSTANCE_MAX2);
                    else {
                        new LiteralStringArray(bc.getFactory(), miss.getAlias()).writeOut(bc, Expression.MODE_REF);
                        adapter.invokeStatic(MISSING_ATTRIBUTE, NEW_INSTANCE_MAX3);
                    }
                    av.visitEndItem(bc.getAdapter());
                }
                av.visitEnd();
            } else {
                ASMConstants.NULL(adapter);
            }
            // /
            attrColl.getValue().writeOut(bc, Expression.MODE_REF);
            adapter.push(attrType);
            adapter.invokeStatic(TAG_UTIL, SET_ATTRIBUTE_COLLECTION);
        }
    }
    // metadata
    Attribute attr;
    Map<String, Attribute> metadata = tag.getMetaData();
    if (metadata != null) {
        Iterator<Attribute> it = metadata.values().iterator();
        while (it.hasNext()) {
            attr = it.next();
            adapter.loadLocal(currLocal);
            adapter.push(attr.getName());
            attr.getValue().writeOut(bc, Expression.MODE_REF);
            if (fromBundle)
                ASMUtil.invoke(ASMUtil.STATIC, adapter, Types.TAG_UTIL, SET_META_DATA3);
            else
                ASMUtil.invoke(ASMUtil.VIRTUAL, adapter, currType, SET_META_DATA2);
        }
    }
    // set attributes
    setAttributes(bc, tag, currLocal, currType, false, fromBundle);
    // Body
    if (hasBody) {
        final int state = adapter.newLocal(Types.INT_VALUE);
        // int state=tag.doStartTag();
        adapter.loadLocal(currLocal);
        ASMUtil.invoke(fromBundle ? ASMUtil.INTERFACE : ASMUtil.VIRTUAL, adapter, currType, DO_START_TAG);
        // adapter.invokeVirtual(currType, DO_START_TAG);
        adapter.storeLocal(state);
        // if (state!=Tag.SKIP_BODY)
        Label endBody = new Label();
        adapter.loadLocal(state);
        adapter.push(javax.servlet.jsp.tagext.Tag.SKIP_BODY);
        adapter.visitJumpInsn(Opcodes.IF_ICMPEQ, endBody);
        // pc.initBody(tag, state);
        adapter.loadArg(0);
        adapter.loadLocal(currLocal);
        adapter.loadLocal(state);
        adapter.invokeVirtual(Types.PAGE_CONTEXT, INIT_BODY);
        OnFinally onFinally = new OnFinally() {

            @Override
            public void _writeOut(BytecodeContext bc) {
                Label endIf = new Label();
                /*if(tlt.handleException() && fcf!=null && fcf.getAfterFinalGOTOLabel()!=null){
							ASMUtil.visitLabel(adapter, fcf.getFinalEntryLabel());
						}*/
                adapter.loadLocal(state);
                adapter.push(javax.servlet.jsp.tagext.Tag.EVAL_BODY_INCLUDE);
                adapter.visitJumpInsn(Opcodes.IF_ICMPEQ, endIf);
                // ... pc.popBody();
                adapter.loadArg(0);
                adapter.invokeVirtual(Types.PAGE_CONTEXT, POP_BODY);
                adapter.pop();
                adapter.visitLabel(endIf);
                // tag.doFinally();
                if (tlt.handleException()) {
                    adapter.loadLocal(currLocal);
                    ASMUtil.invoke(fromBundle ? ASMUtil.INTERFACE : ASMUtil.VIRTUAL, adapter, currType, DO_FINALLY);
                // adapter.invokeVirtual(currType, DO_FINALLY);
                }
            // GOTO after execution body, used when a continue/break was called before
            /*if(fcf!=null) {
							Label l = fcf.getAfterFinalGOTOLabel();
							if(l!=null)adapter.visitJumpInsn(Opcodes.GOTO, l);
						}*/
            }
        };
        if (tlt.handleException()) {
            TryCatchFinallyVisitor tcfv = new TryCatchFinallyVisitor(onFinally, fcf);
            tcfv.visitTryBegin(bc);
            doTry(bc, adapter, tag, currLocal, currType, fromBundle);
            int t = tcfv.visitTryEndCatchBeging(bc);
            // tag.doCatch(t);
            adapter.loadLocal(currLocal);
            adapter.loadLocal(t);
            // adapter.visitVarInsn(Opcodes.ALOAD,t);
            ASMUtil.invoke(fromBundle ? ASMUtil.INTERFACE : ASMUtil.VIRTUAL, adapter, currType, DO_CATCH);
            // adapter.invokeVirtual(currType, DO_CATCH);
            tcfv.visitCatchEnd(bc);
        } else {
            TryFinallyVisitor tfv = new TryFinallyVisitor(onFinally, fcf);
            tfv.visitTryBegin(bc);
            doTry(bc, adapter, tag, currLocal, currType, fromBundle);
            tfv.visitTryEnd(bc);
        }
        adapter.visitLabel(endBody);
    } else {
        // tag.doStartTag();
        adapter.loadLocal(currLocal);
        ASMUtil.invoke(fromBundle ? ASMUtil.INTERFACE : ASMUtil.VIRTUAL, adapter, currType, DO_START_TAG);
        // adapter.invokeVirtual(currType, DO_START_TAG);
        adapter.pop();
    }
    // if (tag.doEndTag()==Tag.SKIP_PAGE) throw new Abort(0<!-- SCOPE_PAGE -->);
    Label endDoEndTag = new Label();
    adapter.loadLocal(currLocal);
    ASMUtil.invoke(fromBundle ? ASMUtil.INTERFACE : ASMUtil.VIRTUAL, adapter, currType, DO_END_TAG);
    // adapter.invokeVirtual(currType, DO_END_TAG);
    adapter.push(javax.servlet.jsp.tagext.Tag.SKIP_PAGE);
    adapter.visitJumpInsn(Opcodes.IF_ICMPNE, endDoEndTag);
    adapter.push(Abort.SCOPE_PAGE);
    adapter.invokeStatic(ABORT, NEW_INSTANCE);
    adapter.throwException();
    adapter.visitLabel(endDoEndTag);
    if (doReuse) {
        // } finally{pc.reuse(tag);}
        outerTcfv.visitTryEnd(bc);
    }
    adapter.visitLabel(tagEnd);
    ExpressionUtil.visitLine(bc, tag.getEnd());
}
Also used : TagLibTagAttr(lucee.transformer.library.tag.TagLibTagAttr) TagLibTag(lucee.transformer.library.tag.TagLibTag) LiteralStringArray(lucee.transformer.bytecode.expression.type.LiteralStringArray) MissingAttribute(lucee.runtime.tag.MissingAttribute) Label(org.objectweb.asm.Label) ClassDefinition(lucee.runtime.db.ClassDefinition) ClassException(lucee.commons.lang.ClassException) TransformerException(lucee.transformer.TransformerException) BundleException(org.osgi.framework.BundleException) Type(org.objectweb.asm.Type) OnFinally(lucee.transformer.bytecode.visitor.OnFinally) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) TryCatchFinallyVisitor(lucee.transformer.bytecode.visitor.TryCatchFinallyVisitor) ArrayVisitor(lucee.transformer.bytecode.visitor.ArrayVisitor) TryFinallyVisitor(lucee.transformer.bytecode.visitor.TryFinallyVisitor) TransformerException(lucee.transformer.TransformerException) BytecodeContext(lucee.transformer.bytecode.BytecodeContext)

Example 4 with OnFinally

use of lucee.transformer.bytecode.visitor.OnFinally in project Lucee by lucee.

the class SourceLastModifiedClassAdapter method writeOutStaticConstructor.

private void writeOutStaticConstructor(ConstrBytecodeContext constr, List<LitString> keys, ClassWriter cw, TagCIObject component, String name) throws TransformerException {
    // if(true) return;
    final GeneratorAdapter adapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, STATIC_COMPONENT_CONSTR, null, new Type[] { Types.PAGE_EXCEPTION }, cw);
    BytecodeContext bc = new BytecodeContext(null, constr, this, keys, cw, name, adapter, STATIC_COMPONENT_CONSTR, writeLog(), suppressWSbeforeArg, output, returnValue);
    Label methodBegin = new Label();
    Label methodEnd = new Label();
    // Scope oldData=null;
    final int oldData = adapter.newLocal(Types.VARIABLES);
    ASMConstants.NULL(adapter);
    adapter.storeLocal(oldData);
    // push body
    int localBC = adapter.newLocal(Types.BODY_CONTENT);
    adapter.loadArg(0);
    adapter.invokeVirtual(Types.PAGE_CONTEXT, PUSH_BODY);
    adapter.storeLocal(localBC);
    // int oldCheckArgs=	pc.undefinedScope().setMode(Undefined.MODE_NO_LOCAL_AND_ARGUMENTS);
    final int oldCheckArgs = adapter.newLocal(Types.INT_VALUE);
    adapter.loadArg(0);
    adapter.invokeVirtual(Types.PAGE_CONTEXT, UNDEFINED_SCOPE);
    adapter.push(Undefined.MODE_NO_LOCAL_AND_ARGUMENTS);
    adapter.invokeInterface(Types.UNDEFINED, SET_MODE);
    adapter.storeLocal(oldCheckArgs);
    TryCatchFinallyVisitor tcf = new TryCatchFinallyVisitor(new OnFinally() {

        public void _writeOut(BytecodeContext bc) {
            // undefined.setMode(oldMode);
            adapter.loadArg(0);
            adapter.invokeVirtual(Types.PAGE_CONTEXT, UNDEFINED_SCOPE);
            adapter.loadLocal(oldCheckArgs, Types.INT_VALUE);
            adapter.invokeInterface(Types.UNDEFINED, SET_MODE);
            adapter.pop();
            // c.afterCall(pc,_oldData);
            // adapter.loadThis();
            adapter.loadArg(1);
            adapter.loadArg(0);
            // old variables scope
            adapter.loadLocal(oldData);
            adapter.invokeVirtual(Types.COMPONENT_IMPL, AFTER_STATIC_CONSTR);
        }
    }, null);
    tcf.visitTryBegin(bc);
    // oldData=c.beforeCall(pc);
    adapter.loadArg(1);
    adapter.loadArg(0);
    adapter.invokeVirtual(Types.COMPONENT_IMPL, BEFORE_STATIC_CONSTR);
    adapter.storeLocal(oldData);
    // ExpressionUtil.visitLine(bc, component.getStart());
    List<StaticBody> list = component.getStaticBodies();
    if (list != null) {
        writeOutConstrBody(bc, list, IFunction.PAGE_TYPE_COMPONENT);
    }
    // ExpressionUtil.visitLine(bc, component.getEnd());
    int t = tcf.visitTryEndCatchBeging(bc);
    // BodyContentUtil.flushAndPop(pc,bc);
    adapter.loadArg(0);
    adapter.loadLocal(localBC);
    adapter.invokeStatic(Types.BODY_CONTENT_UTIL, FLUSH_AND_POP);
    // throw Caster.toPageException(t);
    adapter.loadLocal(t);
    adapter.invokeStatic(Types.CASTER, TO_PAGE_EXCEPTION);
    adapter.throwException();
    tcf.visitCatchEnd(bc);
    adapter.loadArg(0);
    adapter.loadLocal(localBC);
    // TODO why does the body constuctor call clear and it works?
    adapter.invokeStatic(Types.BODY_CONTENT_UTIL, FLUSH_AND_POP);
    adapter.returnValue();
    adapter.visitLabel(methodEnd);
    adapter.endMethod();
}
Also used : Label(org.objectweb.asm.Label) OnFinally(lucee.transformer.bytecode.visitor.OnFinally) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) TryCatchFinallyVisitor(lucee.transformer.bytecode.visitor.TryCatchFinallyVisitor)

Example 5 with OnFinally

use of lucee.transformer.bytecode.visitor.OnFinally in project Lucee by lucee.

the class SourceLastModifiedClassAdapter method writeOutInitComponent.

private void writeOutInitComponent(ConstrBytecodeContext constr, List<LitString> keys, ClassWriter cw, Tag component, String name) throws TransformerException {
    final GeneratorAdapter adapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, INIT_COMPONENT3, null, new Type[] { Types.PAGE_EXCEPTION }, cw);
    BytecodeContext bc = new BytecodeContext(null, constr, this, keys, cw, name, adapter, INIT_COMPONENT3, writeLog(), suppressWSbeforeArg, output, returnValue);
    Label methodBegin = new Label();
    Label methodEnd = new Label();
    adapter.visitLocalVariable("this", "L" + name + ";", null, methodBegin, methodEnd, 0);
    adapter.visitLabel(methodBegin);
    // Scope oldData=null;
    final int oldData = adapter.newLocal(Types.VARIABLES);
    ASMConstants.NULL(adapter);
    adapter.storeLocal(oldData);
    int localBC = adapter.newLocal(Types.BODY_CONTENT);
    ConditionVisitor cv = new ConditionVisitor();
    cv.visitBefore();
    cv.visitWhenBeforeExpr();
    adapter.loadArg(1);
    adapter.invokeVirtual(Types.COMPONENT_IMPL, GET_OUTPUT);
    cv.visitWhenAfterExprBeforeBody(bc);
    ASMConstants.NULL(adapter);
    cv.visitWhenAfterBody(bc);
    cv.visitOtherviseBeforeBody();
    adapter.loadArg(0);
    adapter.invokeVirtual(Types.PAGE_CONTEXT, PUSH_BODY);
    cv.visitOtherviseAfterBody();
    cv.visitAfter(bc);
    adapter.storeLocal(localBC);
    // c.init(pc,this);
    adapter.loadArg(1);
    adapter.loadArg(0);
    adapter.loadThis();
    adapter.loadArg(2);
    // adapter.visitVarInsn(Opcodes.ALOAD, 0);
    adapter.invokeVirtual(Types.COMPONENT_IMPL, INIT_COMPONENT);
    // return when executeConstr is false
    adapter.loadArg(2);
    Label afterIf = new Label();
    adapter.visitJumpInsn(Opcodes.IFNE, afterIf);
    adapter.loadArg(0);
    adapter.loadLocal(localBC);
    adapter.invokeStatic(Types.BODY_CONTENT_UTIL, CLEAR_AND_POP);
    adapter.visitInsn(Opcodes.RETURN);
    adapter.visitLabel(afterIf);
    // int oldCheckArgs=	pc.undefinedScope().setMode(Undefined.MODE_NO_LOCAL_AND_ARGUMENTS);
    final int oldCheckArgs = adapter.newLocal(Types.INT_VALUE);
    adapter.loadArg(0);
    adapter.invokeVirtual(Types.PAGE_CONTEXT, UNDEFINED_SCOPE);
    adapter.push(Undefined.MODE_NO_LOCAL_AND_ARGUMENTS);
    adapter.invokeInterface(Types.UNDEFINED, SET_MODE);
    adapter.storeLocal(oldCheckArgs);
    TryCatchFinallyVisitor tcf = new TryCatchFinallyVisitor(new OnFinally() {

        public void _writeOut(BytecodeContext bc) {
            // undefined.setMode(oldMode);
            adapter.loadArg(0);
            adapter.invokeVirtual(Types.PAGE_CONTEXT, UNDEFINED_SCOPE);
            adapter.loadLocal(oldCheckArgs, Types.INT_VALUE);
            adapter.invokeInterface(Types.UNDEFINED, SET_MODE);
            adapter.pop();
            // c.afterCall(pc,_oldData);
            adapter.loadArg(1);
            adapter.loadArg(0);
            adapter.loadLocal(oldData);
            adapter.invokeVirtual(Types.COMPONENT_IMPL, AFTER_CALL);
        }
    }, null);
    tcf.visitTryBegin(bc);
    // oldData=c.beforeCall(pc);
    adapter.loadArg(1);
    adapter.loadArg(0);
    adapter.invokeVirtual(Types.COMPONENT_IMPL, BEFORE_CALL);
    adapter.storeLocal(oldData);
    ExpressionUtil.visitLine(bc, component.getStart());
    writeOutCallBody(bc, component.getBody(), IFunction.PAGE_TYPE_COMPONENT);
    ExpressionUtil.visitLine(bc, component.getEnd());
    int t = tcf.visitTryEndCatchBeging(bc);
    // BodyContentUtil.flushAndPop(pc,bc);
    adapter.loadArg(0);
    adapter.loadLocal(localBC);
    adapter.invokeStatic(Types.BODY_CONTENT_UTIL, FLUSH_AND_POP);
    // throw Caster.toPageException(t);
    adapter.loadLocal(t);
    adapter.invokeStatic(Types.CASTER, TO_PAGE_EXCEPTION);
    adapter.throwException();
    tcf.visitCatchEnd(bc);
    adapter.loadArg(0);
    adapter.loadLocal(localBC);
    adapter.invokeStatic(Types.BODY_CONTENT_UTIL, CLEAR_AND_POP);
    adapter.returnValue();
    adapter.visitLabel(methodEnd);
    adapter.endMethod();
}
Also used : ConditionVisitor(lucee.transformer.bytecode.visitor.ConditionVisitor) Label(org.objectweb.asm.Label) OnFinally(lucee.transformer.bytecode.visitor.OnFinally) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) TryCatchFinallyVisitor(lucee.transformer.bytecode.visitor.TryCatchFinallyVisitor)

Aggregations

OnFinally (lucee.transformer.bytecode.visitor.OnFinally)12 GeneratorAdapter (org.objectweb.asm.commons.GeneratorAdapter)11 BytecodeContext (lucee.transformer.bytecode.BytecodeContext)9 Label (org.objectweb.asm.Label)8 TryCatchFinallyVisitor (lucee.transformer.bytecode.visitor.TryCatchFinallyVisitor)6 TryFinallyVisitor (lucee.transformer.bytecode.visitor.TryFinallyVisitor)6 TransformerException (lucee.transformer.TransformerException)5 LitString (lucee.transformer.expression.literal.LitString)4 Expression (lucee.transformer.expression.Expression)3 ArrayList (java.util.ArrayList)2 Iterator (java.util.Iterator)2 Body (lucee.transformer.bytecode.Body)2 BodyBase (lucee.transformer.bytecode.BodyBase)2 Statement (lucee.transformer.bytecode.Statement)2 DecisionIntVisitor (lucee.transformer.bytecode.visitor.DecisionIntVisitor)2 WhileVisitor (lucee.transformer.bytecode.visitor.WhileVisitor)2 ClassException (lucee.commons.lang.ClassException)1 ClassDefinition (lucee.runtime.db.ClassDefinition)1 MissingAttribute (lucee.runtime.tag.MissingAttribute)1 LiteralStringArray (lucee.transformer.bytecode.expression.type.LiteralStringArray)1