Search in sources :

Example 1 with ArrayVisitor

use of lucee.transformer.bytecode.visitor.ArrayVisitor 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 2 with ArrayVisitor

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

the class ComponentUtil method createMethod.

private static int createMethod(ConstrBytecodeContext constr, java.util.List<LitString> keys, ClassWriter cw, String className, Object member, int max, boolean writeLog, boolean suppressWSbeforeArg, boolean output, boolean returnValue) throws PageException {
    boolean hasOptionalArgs = false;
    if (member instanceof UDF) {
        UDF udf = (UDF) member;
        FunctionArgument[] args = udf.getFunctionArguments();
        Type[] types = new Type[max < 0 ? args.length : max];
        for (int y = 0; y < types.length; y++) {
            types[y] = toType(args[y].getTypeAsString(), true);
            if (!args[y].isRequired())
                hasOptionalArgs = true;
        }
        Type rtnType = toType(udf.getReturnTypeAsString(), true);
        Method method = new Method(udf.getFunctionName(), rtnType, types);
        GeneratorAdapter adapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, method, null, null, cw);
        BytecodeContext bc = new BytecodeContext(null, constr, getPage(constr), keys, cw, className, adapter, method, writeLog, suppressWSbeforeArg, output, returnValue);
        Label start = adapter.newLabel();
        adapter.visitLabel(start);
        // ComponentController.invoke(name, args);
        // name
        adapter.push(udf.getFunctionName());
        // args
        ArrayVisitor av = new ArrayVisitor();
        av.visitBegin(adapter, Types.OBJECT, types.length);
        for (int y = 0; y < types.length; y++) {
            av.visitBeginItem(adapter, y);
            adapter.loadArg(y);
            av.visitEndItem(bc.getAdapter());
        }
        av.visitEnd();
        adapter.invokeStatic(Types.COMPONENT_CONTROLLER, INVOKE);
        adapter.checkCast(rtnType);
        // ASMConstants.NULL(adapter);
        adapter.returnValue();
        Label end = adapter.newLabel();
        adapter.visitLabel(end);
        for (int y = 0; y < types.length; y++) {
            adapter.visitLocalVariable(args[y].getName().getString(), types[y].getDescriptor(), null, start, end, y + 1);
        }
        adapter.endMethod();
        if (hasOptionalArgs) {
            if (max == -1)
                max = args.length - 1;
            else
                max--;
            return max;
        }
    }
    return -1;
}
Also used : Type(org.objectweb.asm.Type) UDF(lucee.runtime.type.UDF) Label(org.objectweb.asm.Label) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) Method(org.objectweb.asm.commons.Method) ArrayVisitor(lucee.transformer.bytecode.visitor.ArrayVisitor) FunctionArgument(lucee.runtime.type.FunctionArgument) BytecodeContext(lucee.transformer.bytecode.BytecodeContext) ConstrBytecodeContext(lucee.transformer.bytecode.ConstrBytecodeContext)

Example 3 with ArrayVisitor

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

the class SourceLastModifiedClassAdapter method writeGetSubPages.

private void writeGetSubPages(ClassWriter cw, String name, List<TagCIObject> subs, int dialect) {
    // pageSource.getFullClassName().replace('.', '/');
    GeneratorAdapter adapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, GET_SUB_PAGES, null, null, cw);
    Label endIF = new Label();
    // adapter.visitVarInsn(Opcodes.ALOAD, 0);
    // adapter.visitFieldInsn(Opcodes.GETFIELD, name, "subs", "[Llucee/runtime/CIPage;");
    // adapter.visitJumpInsn(Opcodes.IFNONNULL, endIF);
    adapter.visitVarInsn(Opcodes.ALOAD, 0);
    ArrayVisitor av = new ArrayVisitor();
    av.visitBegin(adapter, Types.CI_PAGE, subs.size());
    Iterator<TagCIObject> it = subs.iterator();
    String className;
    int index = 0;
    while (it.hasNext()) {
        TagCIObject ci = it.next();
        av.visitBeginItem(adapter, index++);
        className = createSubClass(name, ci.getName(), dialect);
        // ASMConstants.NULL(adapter);
        adapter.visitTypeInsn(Opcodes.NEW, className);
        adapter.visitInsn(Opcodes.DUP);
        adapter.visitVarInsn(Opcodes.ALOAD, 0);
        adapter.visitMethodInsn(Opcodes.INVOKEVIRTUAL, name, "getPageSource", "()Llucee/runtime/PageSource;");
        adapter.visitMethodInsn(Opcodes.INVOKESPECIAL, className, "<init>", "(Llucee/runtime/PageSource;)V");
        av.visitEndItem(adapter);
    }
    av.visitEnd();
    adapter.visitFieldInsn(Opcodes.PUTFIELD, name, "subs", "[Llucee/runtime/CIPage;");
    // adapter.visitLabel(endIF);
    adapter.visitVarInsn(Opcodes.ALOAD, 0);
    adapter.visitFieldInsn(Opcodes.GETFIELD, name, "subs", "[Llucee/runtime/CIPage;");
    adapter.returnValue();
    adapter.endMethod();
}
Also used : Label(org.objectweb.asm.Label) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) ArrayVisitor(lucee.transformer.bytecode.visitor.ArrayVisitor) LitString(lucee.transformer.expression.literal.LitString) TagCIObject(lucee.transformer.bytecode.statement.tag.TagCIObject)

Example 4 with ArrayVisitor

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

the class CollectionKeyArray method _writeOut.

@Override
public Type _writeOut(BytecodeContext bc, int mode) throws TransformerException {
    GeneratorAdapter adapter = bc.getAdapter();
    ArrayVisitor av = new ArrayVisitor();
    av.visitBegin(adapter, Types.COLLECTION_KEY, arr.length);
    for (int y = 0; y < arr.length; y++) {
        av.visitBeginItem(adapter, y);
        new CollectionKey(getFactory(), arr[y])._writeOut(bc, mode);
        // adapter.push(arr[y]);
        av.visitEndItem(bc.getAdapter());
    }
    av.visitEnd();
    return Types.COLLECTION_KEY_ARRAY;
}
Also used : GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) ArrayVisitor(lucee.transformer.bytecode.visitor.ArrayVisitor)

Example 5 with ArrayVisitor

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

the class LiteralStringArray method _writeOut.

@Override
public Type _writeOut(BytecodeContext bc, int mode) throws TransformerException {
    GeneratorAdapter adapter = bc.getAdapter();
    ArrayVisitor av = new ArrayVisitor();
    av.visitBegin(adapter, Types.STRING, arr.length);
    for (int y = 0; y < arr.length; y++) {
        av.visitBeginItem(adapter, y);
        adapter.push(arr[y]);
        av.visitEndItem(bc.getAdapter());
    }
    av.visitEnd();
    return Types.STRING_ARRAY;
}
Also used : GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) ArrayVisitor(lucee.transformer.bytecode.visitor.ArrayVisitor)

Aggregations

ArrayVisitor (lucee.transformer.bytecode.visitor.ArrayVisitor)11 GeneratorAdapter (org.objectweb.asm.commons.GeneratorAdapter)11 Label (org.objectweb.asm.Label)5 Type (org.objectweb.asm.Type)4 DataMember (lucee.transformer.expression.var.DataMember)3 Member (lucee.transformer.expression.var.Member)3 ArrayList (java.util.ArrayList)2 TransformerException (lucee.transformer.TransformerException)2 BytecodeContext (lucee.transformer.bytecode.BytecodeContext)2 TagCIObject (lucee.transformer.bytecode.statement.tag.TagCIObject)2 LitString (lucee.transformer.expression.literal.LitString)2 Method (org.objectweb.asm.commons.Method)2 IOException (java.io.IOException)1 Method (java.lang.reflect.Method)1 Iterator (java.util.Iterator)1 ClassException (lucee.commons.lang.ClassException)1 RefInteger (lucee.commons.lang.types.RefInteger)1 RefIntegerImpl (lucee.commons.lang.types.RefIntegerImpl)1 InterfacePageImpl (lucee.runtime.InterfacePageImpl)1 PageSource (lucee.runtime.PageSource)1