Example usage for org.objectweb.asm Opcodes ACC_PUBLIC

List of usage examples for org.objectweb.asm Opcodes ACC_PUBLIC

Introduction

In this page you can find the example usage for org.objectweb.asm Opcodes ACC_PUBLIC.

Prototype

int ACC_PUBLIC

To view the source code for org.objectweb.asm Opcodes ACC_PUBLIC.

Click Source Link

Usage

From source file:jpcsp.Allegrex.compiler.CodeBlock.java

License:Open Source License

private void addConstructor(ClassVisitor cv) {
    MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
    mv.visitCode();/* w  w  w  . ja va 2  s  . c o  m*/
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, objectInternalName, "<init>", "()V");
    mv.visitInsn(Opcodes.RETURN);
    mv.visitMaxs(1, 1);
    mv.visitEnd();
}

From source file:jpcsp.Allegrex.compiler.CodeBlock.java

License:Open Source License

private void addNonStaticMethods(CompilerContext context, ClassVisitor cv) {
    MethodVisitor mv;/*from   ww  w.jav  a  2 s.  c o m*/

    // public int exec(int returnAddress, int alternativeReturnAddress, boolean isJump) throws Exception;
    mv = cv.visitMethod(Opcodes.ACC_PUBLIC, context.getExecMethodName(), context.getExecMethodDesc(), null,
            exceptions);
    mv.visitCode();
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, getClassName(), context.getStaticExecMethodName(),
            context.getStaticExecMethodDesc());
    mv.visitInsn(Opcodes.IRETURN);
    mv.visitMaxs(1, 1);
    mv.visitEnd();

    // private static IExecutable e;
    FieldVisitor fv = cv.visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC, context.getReplaceFieldName(),
            executableDescriptor, null, null);
    fv.visitEnd();

    // public void setExecutable(IExecutable e);
    mv = cv.visitMethod(Opcodes.ACC_PUBLIC, context.getReplaceMethodName(), context.getReplaceMethodDesc(),
            null, exceptions);
    mv.visitCode();
    mv.visitVarInsn(Opcodes.ALOAD, 1);
    mv.visitFieldInsn(Opcodes.PUTSTATIC, getClassName(), context.getReplaceFieldName(), executableDescriptor);
    mv.visitInsn(Opcodes.RETURN);
    mv.visitMaxs(1, 2);
    mv.visitEnd();

    // public IExecutable getExecutable();
    mv = cv.visitMethod(Opcodes.ACC_PUBLIC, context.getGetMethodName(), context.getGetMethodDesc(), null,
            exceptions);
    mv.visitCode();
    mv.visitFieldInsn(Opcodes.GETSTATIC, getClassName(), context.getReplaceFieldName(), executableDescriptor);
    mv.visitInsn(Opcodes.ARETURN);
    mv.visitMaxs(1, 1);
    mv.visitEnd();
}

From source file:jpcsp.Allegrex.compiler.CodeBlock.java

License:Open Source License

private Class<IExecutable> interpret(CompilerContext context) {
    Class<IExecutable> compiledClass = null;

    context.setCodeBlock(this);
    String className = getInternalClassName();
    if (log.isInfoEnabled()) {
        log.info("Compiling for Interpreter " + className);
    }/* ww  w .j  a  v a2 s.c om*/

    int computeFlag = ClassWriter.COMPUTE_FRAMES;
    if (context.isAutomaticMaxLocals() || context.isAutomaticMaxStack()) {
        computeFlag |= ClassWriter.COMPUTE_MAXS;
    }
    ClassWriter cw = new ClassWriter(computeFlag);
    ClassVisitor cv = cw;
    if (log.isDebugEnabled()) {
        cv = new CheckClassAdapter(cv);
    }

    StringWriter debugOutput = null;
    if (log.isDebugEnabled()) {
        debugOutput = new StringWriter();
        PrintWriter debugPrintWriter = new PrintWriter(debugOutput);
        cv = new TraceClassVisitor(cv, debugPrintWriter);
    }
    cv.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER, className, null, objectInternalName,
            interfacesForExecutable);
    context.startClass(cv);

    addConstructor(cv);
    addNonStaticMethods(context, cv);

    MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,
            context.getStaticExecMethodName(), context.getStaticExecMethodDesc(), null, exceptions);
    mv.visitCode();
    context.setMethodVisitor(mv);
    context.startMethod();

    context.compileExecuteInterpreter(getStartAddress());

    mv.visitMaxs(context.getMaxStack(), context.getMaxLocals());
    mv.visitEnd();

    cv.visitEnd();

    if (debugOutput != null) {
        log.debug(debugOutput.toString());
    }

    compiledClass = loadExecutable(context, className, cw.toByteArray());

    return compiledClass;
}

From source file:jpcsp.Allegrex.compiler.CodeBlock.java

License:Open Source License

private Class<IExecutable> compile(CompilerContext context) throws ClassFormatError {
    Class<IExecutable> compiledClass = null;

    context.setCodeBlock(this);
    String className = getInternalClassName();
    if (log.isDebugEnabled()) {
        String functionName = Utilities.getFunctionNameByAddress(getStartAddress());

        if (functionName != null) {
            log.debug(String.format("Compiling %s (%s)", className, functionName));
        } else {/*from w  w w .  j a v a 2  s  .c  om*/
            log.debug(String.format("Compiling %s", className));
        }
    }

    prepare(context, context.getMethodMaxInstructions());

    currentSequence = null;
    int computeFlag = ClassWriter.COMPUTE_FRAMES;
    if (context.isAutomaticMaxLocals() || context.isAutomaticMaxStack()) {
        computeFlag |= ClassWriter.COMPUTE_MAXS;
    }
    ClassWriter cw = new ClassWriter(computeFlag);
    ClassVisitor cv = cw;
    if (log.isDebugEnabled()) {
        cv = new CheckClassAdapter(cv);
    }
    StringWriter debugOutput = null;
    if (log.isTraceEnabled()) {
        debugOutput = new StringWriter();
        PrintWriter debugPrintWriter = new PrintWriter(debugOutput);
        cv = new TraceClassVisitor(cv, debugPrintWriter);
    }
    cv.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER, className, null, objectInternalName,
            interfacesForExecutable);
    context.startClass(cv);

    addConstructor(cv);
    addNonStaticMethods(context, cv);

    MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,
            context.getStaticExecMethodName(), context.getStaticExecMethodDesc(), null, exceptions);
    mv.visitCode();
    context.setMethodVisitor(mv);
    context.startMethod();

    // Jump to the block start if other instructions have been inserted in front
    if (!codeInstructions.isEmpty() && codeInstructions.getFirst().getAddress() != getStartAddress()) {
        mv.visitJumpInsn(Opcodes.GOTO, getCodeInstruction(getStartAddress()).getLabel());
    }

    compile(context, mv, codeInstructions);
    mv.visitMaxs(context.getMaxStack(), context.getMaxLocals());
    mv.visitEnd();

    for (SequenceCodeInstruction sequenceCodeInstruction : sequenceCodeInstructions) {
        if (log.isDebugEnabled()) {
            log.debug("Compiling Sequence " + sequenceCodeInstruction.getMethodName(context));
        }
        currentSequence = sequenceCodeInstruction;
        mv = cv.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,
                sequenceCodeInstruction.getMethodName(context), "()V", null, exceptions);
        mv.visitCode();
        context.setMethodVisitor(mv);
        context.startSequenceMethod();

        compile(context, mv, sequenceCodeInstruction.getCodeSequence().getInstructions());

        context.endSequenceMethod();
        mv.visitMaxs(context.getMaxStack(), context.getMaxLocals());
        mv.visitEnd();
    }
    currentSequence = null;

    cv.visitEnd();

    if (debugOutput != null) {
        log.trace(debugOutput.toString());
    }

    try {
        compiledClass = loadExecutable(context, className, cw.toByteArray());
    } catch (NullPointerException e) {
        log.error("Error while compiling " + className + ": " + e);
    }

    return compiledClass;
}

From source file:lapin.comp.asm.ASMByteCodeGenerator.java

License:Open Source License

private void initASMObject(Env env) {
    ArrayList al = new ArrayList();
    for (Object l = ciList; !Lists.isEnd(l); l = Lists.cdr(l)) {
        CallableInfo ci = (CallableInfo) Lists.car(l);
        if (ci.mi.implCallable())
            al.add(toInternalName(ci.interfaceName));
    }/*from  w w w  .ja  va 2 s .  c  o  m*/
    String[] ifNames = new String[al.size()];
    al.toArray(ifNames);
    // ClassWriter
    _cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    _cw.visit(Opcodes.V1_1, Opcodes.ACC_PUBLIC, toInternalName(super.classInfo.classname()), null,
            "lapin/function/CompiledExpr", ifNames);
}

From source file:lapin.comp.asm.ASMByteCodeGenerator.java

License:Open Source License

private void generateConstructor(Env env) {
    /*//from   w  w w.  j a  v  a 2s . co  m
     * local variables (reserved)
     * 0: this
     * 1: env
     */
    MethodVisitor mv = _cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>",
            //"(Llapin/lang/Env;)V",
            Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { TYPE_ENV }), null, null);

    mv.visitCode();
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitLdcInsn(super.classInfo.name().pname());
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "lapin/function/CompiledExpr", "<init>",
            //"(Ljava/lang/String;)V");
            Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { TYPE_STRING }));

    Iterator it;

    // fields for constants
    it = constTable.keySet().iterator();
    while (it.hasNext()) {
        Object key = it.next(); // key: object (const)
        String val = Data.string(constTable.get(key));
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitLdcInsn(Printer.prin1ToString(key, env));
        mv.visitVarInsn(Opcodes.ALOAD, 1);
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "lapin/function/CompiledExpr", "toSexp",
                Type.getMethodDescriptor(TYPE_OBJECT, new Type[] { TYPE_STRING, TYPE_ENV }));
        mv.visitFieldInsn(Opcodes.PUTFIELD, toInternalName(super.classInfo.classname()), val,
                TYPE_OBJECT.getDescriptor());
    }

    // fields for vars
    it = varTable.keySet().iterator();
    while (it.hasNext()) {
        Object key = it.next(); // key: symbol (var)
        String val = Data.string(varTable.get(key));
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitLdcInsn(Printer.prin1ToString(key, env));
        mv.visitVarInsn(Opcodes.ALOAD, 1);
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "lapin/function/CompiledExpr", "toSexp",
                Type.getMethodDescriptor(TYPE_OBJECT, new Type[] { TYPE_STRING, TYPE_ENV }));
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "lapin/lang/Data", "symbol",
                Type.getMethodDescriptor(TYPE_SYMBOL, new Type[] { TYPE_OBJECT }));
        mv.visitFieldInsn(Opcodes.PUTFIELD, toInternalName(super.classInfo.classname()), val,
                TYPE_SYMBOL.getDescriptor());
    }

    // fields for lambdaLists
    it = llTable.keySet().iterator();
    while (it.hasNext()) {
        Object key = it.next(); // key: lambdaList
        String val = Data.string(llTable.get(key));
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitLdcInsn(Printer.prin1ToString(Data.lambdaList(key).params(), env));
        mv.visitVarInsn(Opcodes.ALOAD, 1);
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "lapin/function/CompiledExpr", "toLambdaList",
                Type.getMethodDescriptor(TYPE_LAMBDA_LIST, new Type[] { TYPE_STRING, TYPE_ENV }));
        mv.visitFieldInsn(Opcodes.PUTFIELD, toInternalName(super.classInfo.classname()), val,
                TYPE_LAMBDA_LIST.getDescriptor());
    }

    // field for SELF (static field)
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.PUTSTATIC, toInternalName(super.classInfo.classname()), "SELF",
            toTypeDescriptor(super.classInfo.classname()));
    mv.visitInsn(Opcodes.RETURN);

    mv.visitMaxs(0, 0);
    mv.visitEnd();
}

From source file:lapin.comp.asm.ASMByteCodeGenerator.java

License:Open Source License

private void generateCall(CallableInfo ci, Env env) {
    /*// w  w w  . j  av a 2  s .co m
     * local variables
     * <Callable#call>
     * 0: this
     * 1: args (list of arguments)
     * 2: env
     *
     * <Callable0#call0>
     * 0: this
     * 1: env
     *
     * <Callable1#call1>
     * 0: this
     * 1: arg0
     * 2: env
     *
     * <Callable2#call2>
     * 0: this
     * 1: arg0
     * 2: arg1
     * 3: env
     *
     * ...
     *
     */
    MethodVisitor mv = _cw.visitMethod(
            ci.mi.implCallable() ? Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL : Opcodes.ACC_FINAL, ci.mi.name(),
            Type.getMethodDescriptor(ci.retType, ci.paramTypes), null, null);

    // instruction list
    int len = ci.mi.instLen();
    // label
    Label label = null;

    // generate code
    for (int i = 0; i < len; i++) {
        Object inst = ci.mi.getInst(i);
        if (Logger.tracelevelp(env))
            Logger.trace("[asm:gen]" + i + ":\t~S", Lists.list(inst), env);

        // inst is symbol
        // -> convert tag (Symbol) to label (ASMe Label object)
        if (Data.isSymbol(inst)) {
            Symbol tag = Data.symbol(inst);
            Label l = (Label) ci.labelTable.get(tag);
            if (l == null) {
                throw new NotReachedException("label is null: ~S.", Lists.list(tag));
            } else if (l != label) {
                mv.visitLabel(l);
                label = l;
                if (Logger.tracelevelp(env))
                    Logger.trace("[asm:gen]" + i + ":\ttag ~S -> label ~S", Lists.list(tag, l), env);
            } else {
                if (Logger.tracelevelp(env))
                    Logger.trace("[asm:gen]" + i + ":\ttag ~S -> label ~S" + " (dup)", Lists.list(tag, l), env);
            }
            continue;
        }

        // inst must be the form of (id <arg1> <arg2> ....)
        Object id = Lists.car(inst);
        if (id == Insts.CONST) {
            /* push const on the stack. */
            Object obj = Lists.cadr(inst);
            String val = Data.string(constTable.get(obj));
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            mv.visitFieldInsn(Opcodes.GETFIELD, toInternalName(super.classInfo.classname()), val,
                    TYPE_OBJECT.getDescriptor());
        } else if (id == Insts.VAR) {
            /* push var on the stack */
            Object var = Lists.cadr(inst);
            String val = Data.string(varTable.get(var));
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            mv.visitFieldInsn(Opcodes.GETFIELD, toInternalName(super.classInfo.classname()), val,
                    TYPE_SYMBOL.getDescriptor());
        } else if (id == Insts.LAMBDA_LIST) {
            /* push lambdaList on the stack */
            Object var = Lists.cadr(inst);
            /* push _ll_<i> on the stack */
            String val = Data.string(llTable.get(var));
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            mv.visitFieldInsn(Opcodes.GETFIELD, toInternalName(super.classInfo.classname()), val,
                    TYPE_LAMBDA_LIST.getDescriptor());
        } else if (id == Insts.ENV_GET) {
            /* env.get */
            Class type = Data.javaClass(Lists.cadr(inst));
            if (type.equals(int.class)) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "getInt",
                        Type.getMethodDescriptor(Type.INT_TYPE, new Type[] { TYPE_SYMBOL }));
            } else if (type.equals(double.class)) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "getDouble",
                        Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[] { TYPE_SYMBOL }));
            } else if (type.equals(char.class)) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "getChar",
                        Type.getMethodDescriptor(Type.CHAR_TYPE, new Type[] { TYPE_SYMBOL }));
            } else if (Object.class.isAssignableFrom(type)) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "get",
                        Type.getMethodDescriptor(TYPE_OBJECT, new Type[] { TYPE_SYMBOL }));
            } else {
                throw new NotReachedException("unsupported type: ~S.", Lists.list(type));
            }
        } else if (id == Insts.ENV_SET) {
            /* env.set */
            Class type = Data.javaClass(Lists.cadr(inst));
            if (type.equals(int.class)) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "set",
                        Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { TYPE_SYMBOL, Type.INT_TYPE }));
            } else if (type.equals(double.class)) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "set",
                        Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { TYPE_SYMBOL, Type.DOUBLE_TYPE }));
            } else if (type.equals(char.class)) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "set",
                        Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { TYPE_SYMBOL, Type.CHAR_TYPE }));
            } else if (Object.class.isAssignableFrom(type)) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "set",
                        Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { TYPE_SYMBOL, TYPE_OBJECT }));
            } else {
                throw new NotReachedException("unsupported type: ~S.", Lists.list(type));
            }
        } else if (id == Insts.ENV_BIND) {
            /* env.bind */
            Class type = Data.javaClass(Lists.cadr(inst));
            if (type.equals(int.class)) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "bind",
                        Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { TYPE_SYMBOL, Type.INT_TYPE }));
            } else if (type.equals(double.class)) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "bind",
                        Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { TYPE_SYMBOL, Type.DOUBLE_TYPE }));
            } else if (type.equals(char.class)) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "bind",
                        Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { TYPE_SYMBOL, Type.CHAR_TYPE }));
            } else if (Object.class.isAssignableFrom(type)) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "bind",
                        Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { TYPE_SYMBOL, TYPE_OBJECT }));
            } else {
                throw new NotReachedException("unsupported type: ~S.", Lists.list(type));
            }
        } else if (id == Insts.ENV_UNBIND) {
            /* env.unbind */
            Class type = Data.javaClass(Lists.cadr(inst));
            if (type.equals(int.class)) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "unbindInt",
                        Type.getMethodDescriptor(Type.INT_TYPE, new Type[] { TYPE_SYMBOL }));
            } else if (type.equals(double.class)) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "unbindDouble",
                        Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[] { TYPE_SYMBOL }));
            } else if (type.equals(char.class)) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "unbindChar",
                        Type.getMethodDescriptor(Type.CHAR_TYPE, new Type[] { TYPE_SYMBOL }));
            } else if (Object.class.isAssignableFrom(type)) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "unbind",
                        Type.getMethodDescriptor(TYPE_OBJECT, new Type[] { TYPE_SYMBOL }));
            } else {
                throw new NotReachedException("unsupported type: ~S.", Lists.list(type));
            }
        } else if (id == Insts.ENV_CHILD) {
            /* env.child */
            Object oldEnvVar = Lists.cadr(inst);
            Object newEnvVar = Lists.caddr(inst);
            Object oldSlot = Lists.cadr(oldEnvVar);
            Object newSlot = Lists.cadr(newEnvVar);
            int oldLocal = Data.fixnum(ci.localTable.get(oldSlot)).intValue();
            int newLocal = Data.fixnum(ci.localTable.get(newSlot)).intValue();
            if (Logger.tracelevelp(env))
                Logger.trace("[asm:gen]" + i + ":\tenv-child: local ~S -> ~S",
                        Lists.list(Data.toFixnum(oldLocal), Data.toFixnum(newLocal)), env);
            mv.visitVarInsn(Opcodes.ALOAD, oldLocal);
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "child",
                    Type.getMethodDescriptor(TYPE_ENV, TYPE_NO_ARGS));
            mv.visitVarInsn(Opcodes.ASTORE, newLocal);
        } else if (id == Insts.CALL) {
            /* funcall */
            int nargs = Data.fixnum(Lists.cadr(inst)).intValue();
            String className = "lapin.eval.Funcall";
            String methodName = nargs < 0 ? "funcall" : "funcall" + nargs;
            Class rType = Object.class;
            Class[] pTypes;
            if (nargs < 0) {
                pTypes = new Class[] { Function.class, Object.class, // list of args
                        Env.class };
            } else {
                pTypes = new Class[nargs + 2];
                pTypes[0] = Function.class;
                for (int j = 0; j < nargs; j++) {
                    pTypes[j + 1] = Object.class;
                }
                pTypes[nargs + 1] = Env.class;
            }

            Type retType = Type.getType(rType);
            Type[] paramTypes = new Type[pTypes.length];
            for (int j = 0; j < pTypes.length; j++)
                paramTypes[j] = Type.getType(pTypes[j]);

            mv.visitMethodInsn(Opcodes.INVOKESTATIC, toInternalName(className), methodName,
                    Type.getMethodDescriptor(retType, paramTypes));
        } else if (id == Insts.CALL_DIRECT) {
            /*
             * public class Foo
             *   extends CompiledExpr implements Callable2 {
             *  public Object call2(Object arg0, Object arg1, Env env) {
             *   ...
             *  }
             * }
             */
            MethodInfo mi = (MethodInfo) Lists.cadr(inst);
            String className = mi.classInfo().classname();
            int nargs = mi.nargs();
            boolean rest = mi.rest();
            String methodName = mi.name();
            Class rType = mi.retType();
            Class[] pTypes = mi.paramTypes();

            Type retType = Type.getType(rType);
            Type[] paramTypes = new Type[pTypes.length];
            for (int j = 0; j < pTypes.length; j++)
                paramTypes[j] = Type.getType(pTypes[j]);

            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, toInternalName(className), methodName,
                    Type.getMethodDescriptor(retType, paramTypes));
        } else if (id == Insts.COMPILED_EXPR) {
            /*
             * public class Foo extends CompiledExpr {
             *  static public Foo SELF;
             *  ...
             * }
             */
            String className = Data.string(Lists.cadr(inst));
            String fieldName = "SELF";
            String typeName = className;
            mv.visitFieldInsn(Opcodes.GETSTATIC, toInternalName(className), fieldName,
                    toTypeDescriptor(typeName));
        } else if (id == Insts.RETURN) {
            /* return */
            Class type = Data.javaClass(Lists.cadr(inst));
            if (type.equals(int.class) || type.equals(short.class) || type.equals(byte.class)
                    || type.equals(char.class)) {
                mv.visitInsn(Opcodes.IRETURN);
            } else if (type.equals(long.class)) {
                mv.visitInsn(Opcodes.LRETURN);
            } else if (type.equals(float.class)) {
                mv.visitInsn(Opcodes.FRETURN);
            } else if (type.equals(double.class)) {
                mv.visitInsn(Opcodes.DRETURN);
            } else if (type.equals(void.class)) {
                //mv.visitInsn(Opcodes.RETURN);
                throw new NotReachedException("unsupported returnType: ~S.", Lists.list(type));
            } else {
                mv.visitInsn(Opcodes.ARETURN);
            }
        } else if (id == Insts.IFEQ) {
            /* conditional jump */
            Symbol tag = Data.symbol(Lists.cadr(inst));
            Label l = (Label) ci.labelTable.get(tag);
            if (l == null) {
                throw new NotReachedException("label not found: ~S.", Lists.list(tag));
            }
            mv.visitJumpInsn(Opcodes.IFEQ, l);
        } else if (id == Insts.IFNE) {
            /* conditional jump */
            Symbol tag = Data.symbol(Lists.cadr(inst));
            Label l = (Label) ci.labelTable.get(tag);
            if (l == null) {
                throw new NotReachedException("label not found: ~S.", Lists.list(tag));
            }
            mv.visitJumpInsn(Opcodes.IFNE, l);
        } else if (id == Insts.GOTO) {
            /* jump */
            Symbol tag = Data.symbol(Lists.cadr(inst));
            Label l = (Label) ci.labelTable.get(tag);
            if (l == null) {
                throw new NotReachedException("label not found: ~S.", Lists.list(tag));
            }
            mv.visitJumpInsn(Opcodes.GOTO, l);
        } else if (id == Insts.LOAD) {
            /* local -> stack */
            Object localVar = Lists.cadr(inst);
            Object slot = Lists.cadr(localVar);
            Class type = Data.javaClass(Lists.caddr(localVar));
            int local = Data.fixnum(ci.localTable.get(slot)).intValue();
            int op = Type.getType(type).getOpcode(Opcodes.ILOAD);
            if (Logger.tracelevelp(env))
                Logger.trace("[asm:gen]" + i + ":\tload: local=~S type=~S",
                        Lists.list(Data.toFixnum(local), type), env);
            mv.visitVarInsn(op, local);
        } else if (id == Insts.STORE) {
            /* stack -> local */
            Object localVar = Lists.cadr(inst);
            Object slot = Lists.cadr(localVar);
            Class type = Data.javaClass(Lists.caddr(localVar));
            int local = Data.fixnum(ci.localTable.get(slot)).intValue();
            int op = Type.getType(type).getOpcode(Opcodes.ISTORE);
            if (Logger.tracelevelp(env))
                Logger.trace("[asm:gen]" + i + ":\tstore: local=~S type=~S",
                        Lists.list(Data.toFixnum(local), type), env);
            mv.visitVarInsn(op, local);
        } else if (id == Insts.POP) {
            /* pop a value and discard it */
            Class type = Data.javaClass(Lists.cadr(inst));
            int op;
            switch (Classes.sizeOf(type)) {
            case 1:
                op = Opcodes.POP;
                break;
            case 2:
                op = Opcodes.POP2;
                break;
            default:
                throw new NotReachedException("unsupported type: ~S.", Lists.list(type));
            }
            mv.visitInsn(op);
        } else if (id == Insts.DUP) {
            /* peek a value and duplicate it */
            Class type = Data.javaClass(Lists.cadr(inst));
            int op;
            switch (Classes.sizeOf(type)) {
            case 1:
                op = Opcodes.DUP;
                break;
            case 2:
                op = Opcodes.DUP2;
                break;
            default:
                throw new NotReachedException("unsupported type: ~S.", Lists.list(type));
            }
            mv.visitInsn(op);
        } else if (id == Insts.PUSH) {
            /* push a constant */
            Object val = Lists.cadr(inst);
            if (Data.isJavaBoolean(val)) {
                if (Data.javaBoolean(val).booleanValue())
                    mv.visitInsn(Opcodes.ICONST_1);
                else
                    mv.visitInsn(Opcodes.ICONST_0);
            } else if (val instanceof Byte || val instanceof Short || val instanceof Integer) {
                int n = Data.javaNumber(val).intValue();
                if (n == -1)
                    mv.visitInsn(Opcodes.ICONST_M1);
                else if (n == 0)
                    mv.visitInsn(Opcodes.ICONST_0);
                else if (n == 1)
                    mv.visitInsn(Opcodes.ICONST_1);
                else if (n == 2)
                    mv.visitInsn(Opcodes.ICONST_2);
                else if (n == 3)
                    mv.visitInsn(Opcodes.ICONST_3);
                else if (n == 4)
                    mv.visitInsn(Opcodes.ICONST_4);
                else if (n == 5)
                    mv.visitInsn(Opcodes.ICONST_5);
                else if (Byte.MIN_VALUE <= n && n <= Byte.MAX_VALUE)
                    mv.visitIntInsn(Opcodes.BIPUSH, n);
                else if (Short.MIN_VALUE <= n && n <= Short.MAX_VALUE)
                    mv.visitIntInsn(Opcodes.SIPUSH, n);
                else
                    mv.visitLdcInsn(Data.toFixnum(n));
            } else if (val instanceof Long) {
                long n = Data.javaNumber(val).longValue();
                if (n == 0L)
                    mv.visitInsn(Opcodes.LCONST_0);
                else if (n == 1L)
                    mv.visitInsn(Opcodes.LCONST_1);
                else
                    mv.visitLdcInsn(val);
            } else if (val instanceof Float) {
                float n = Data.javaNumber(val).floatValue();
                if (n == 0.0f)
                    mv.visitInsn(Opcodes.FCONST_0);
                else if (n == 1.0f)
                    mv.visitInsn(Opcodes.FCONST_1);
                else if (n == 2.0f)
                    mv.visitInsn(Opcodes.FCONST_2);
                else
                    mv.visitLdcInsn(val);
            } else if (val instanceof Double) {
                double n = Data.javaNumber(val).doubleValue();
                if (n == 0.0)
                    mv.visitInsn(Opcodes.DCONST_0);
                else if (n == 1.0)
                    mv.visitInsn(Opcodes.DCONST_1);
                else
                    mv.visitLdcInsn(val);
            } else if (Data.isCharacter(val)) {
                Character c = Data.character(val);
                int n = (int) c.charValue();
                if (Byte.MIN_VALUE <= n && n <= Byte.MAX_VALUE)
                    mv.visitIntInsn(Opcodes.BIPUSH, n);
                else if (Short.MIN_VALUE <= n && n <= Short.MAX_VALUE)
                    mv.visitIntInsn(Opcodes.SIPUSH, n);
                else
                    mv.visitLdcInsn(Data.toFixnum(n));
            } else if (Data.isString(val)) {
                mv.visitLdcInsn(val);
            } else {
                throw new NotReachedException("cannot push: ~S.", Lists.list(val));
            }
        } else if (id == Insts.GET) {
            Field f = Data.javaField(Lists.cadr(inst));
            String fieldName = f.getName();
            Class c = f.getDeclaringClass();
            String className = c.getName();
            Class t = f.getType();
            String typeName = t.getName();

            boolean isStatic = Classes.isStatic(f);
            int op = isStatic ? Opcodes.GETSTATIC : Opcodes.GETFIELD;

            mv.visitFieldInsn(op, toInternalName(className), fieldName, toTypeDescriptor(typeName));
        } else if (id == Insts.PUT) {
            Field f = Data.javaField(Lists.cadr(inst));
            String fieldName = f.getName();
            Class c = f.getDeclaringClass();
            String className = c.getName();
            Class t = f.getType();
            String typeName = t.getName();

            boolean isStatic = Classes.isStatic(f);
            int op = isStatic ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD;

            mv.visitFieldInsn(op, toInternalName(className), fieldName, toTypeDescriptor(typeName));
        } else if (id == Insts.INVOKE) {
            Method m = Data.javaMethod(Lists.cadr(inst));
            String methodName = m.getName();
            Class c = m.getDeclaringClass();
            String className = c.getName();
            Class rType = m.getReturnType();
            Class[] pTypes = m.getParameterTypes();
            if (rType.equals(void.class)) {
                throw new NotReachedException("unsupported returnType: ~S.", Lists.list(rType));
            }
            Type retType = Type.getType(rType);
            Type[] paramTypes = new Type[pTypes.length];
            for (int j = 0; j < pTypes.length; j++)
                paramTypes[j] = Type.getType(pTypes[j]);

            boolean isStatic = Classes.isStatic(m);
            boolean isInterface = c.isInterface();
            int op = isStatic ? Opcodes.INVOKESTATIC
                    : isInterface ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL;

            mv.visitMethodInsn(op, toInternalName(className), methodName,
                    Type.getMethodDescriptor(retType, paramTypes));
        } else if (id == Insts.CHECKCAST) {
            Class c = Data.javaClass(Lists.cadr(inst));
            Type t = Type.getType(c);
            mv.visitTypeInsn(Opcodes.CHECKCAST, t.getInternalName());
        } else if (id == Insts.THROW) {
            mv.visitInsn(Opcodes.ATHROW);
        } else if (id == Insts.CATCH) {
            Symbol tagS = Data.symbol(Lists.cadr(inst));
            Symbol tagE = Data.symbol(Lists.caddr(inst));
            Symbol tagH = Data.symbol(Lists.cadddr(inst));
            String className;
            if (Lists.isEnd(Lists.cddddr(inst))) {
                className = null;
            } else {
                Class c = Data.javaClass(Lists.car(Lists.cddddr(inst)));
                className = toInternalName(c.getName());
            }
            Label labelS = (Label) ci.labelTable.get(tagS);
            if (labelS == null) {
                throw new NotReachedException("label not found: ~S.", Lists.list(tagS));
            }
            Label labelE = (Label) ci.labelTable.get(tagE);
            if (labelE == null) {
                throw new NotReachedException("label not found: ~S.", Lists.list(tagE));
            }
            Label labelH = (Label) ci.labelTable.get(tagH);
            if (labelH == null) {
                throw new NotReachedException("label not found: ~S.", Lists.list(tagH));
            }
            mv.visitTryCatchBlock(labelS, labelE, labelH, className);
        }
        //else if (id == Insts.CATCH_FROM ||
        //         id == Insts.CATCH_TO ||
        //         id == Insts.CATCH_HANDLER) {
        //    /* nothing emitted */
        //    continue;
        //}
        else {
            throw new NotReachedException("unknown inst: ~S.", Lists.list(inst));
        }
    }
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}

From source file:lucee.runtime.type.util.ComponentUtil.java

License:Open Source License

/**
 * generate a ComponentJavaAccess (CJA) class from a component
 * a CJA is a dynamic genarted java class that has all method defined inside a component as java methods.
* 
* This is used to generated server side Webservices.
* @param component//from  w  ww  . j a va2 s . com
 * @param isNew 
 * @return
 * @throws PageException
 */
public static Class getComponentJavaAccess(PageContext pc, Component component, RefBoolean isNew,
        boolean create, boolean writeLog, boolean suppressWSbeforeArg, boolean output) throws PageException {
    isNew.setValue(false);
    String classNameOriginal = component.getPageSource().getFullClassName();
    String className = getClassname(component, null).concat("_wrap");
    String real = className.replace('.', '/');
    String realOriginal = classNameOriginal.replace('.', '/');
    Mapping mapping = component.getPageSource().getMapping();
    PhysicalClassLoader cl = null;
    try {
        cl = (PhysicalClassLoader) ((PageContextImpl) pc).getRPCClassLoader(false);
    } catch (IOException e) {
        throw Caster.toPageException(e);
    }
    Resource classFile = cl.getDirectory().getRealResource(real.concat(".class"));
    Resource classFileOriginal = mapping.getClassRootDirectory().getRealResource(realOriginal.concat(".class"));

    // LOAD CLASS
    //print.out(className);
    // check last Mod
    if (classFile.lastModified() >= classFileOriginal.lastModified()) {
        try {
            Class clazz = cl.loadClass(className);
            if (clazz != null && !hasChangesOfChildren(classFile.lastModified(), clazz))
                return registerTypeMapping(clazz);
        } catch (Throwable t) {
        }
    }
    if (!create)
        return null;
    isNew.setValue(true);
    //print.out("new");
    // CREATE CLASS   
    ClassWriter cw = ASMUtil.getClassWriter();
    cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC, real, null, "java/lang/Object", null);

    //GeneratorAdapter ga = new GeneratorAdapter(Opcodes.ACC_PUBLIC,Page.STATIC_CONSTRUCTOR,null,null,cw);
    BytecodeContext statConstr = null;//new BytecodeContext(null,null,null,cw,real,ga,Page.STATIC_CONSTRUCTOR);

    ///ga = new GeneratorAdapter(Opcodes.ACC_PUBLIC,Page.CONSTRUCTOR,null,null,cw);
    BytecodeContext constr = null;//new BytecodeContext(null,null,null,cw,real,ga,Page.CONSTRUCTOR);

    // field component
    //FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE, "c", "Llucee/runtime/ComponentImpl;", null, null);
    //fv.visitEnd();

    java.util.List<LitString> _keys = new ArrayList<LitString>();

    // remote methods
    Collection.Key[] keys = ComponentProUtil.keys(component, Component.ACCESS_REMOTE);
    int max;
    for (int i = 0; i < keys.length; i++) {
        max = -1;
        while ((max = createMethod(statConstr, constr, _keys, cw, real, component.get(keys[i]), max, writeLog,
                suppressWSbeforeArg, output)) != -1) {
            break;// for overload remove this
        }
    }

    // Constructor
    GeneratorAdapter adapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC, CONSTRUCTOR_OBJECT, null, null, cw);
    adapter.loadThis();
    adapter.invokeConstructor(Types.OBJECT, CONSTRUCTOR_OBJECT);
    lucee.transformer.bytecode.Page
            .registerFields(new BytecodeContext(null, statConstr, constr, getPage(statConstr, constr), _keys,
                    cw, real, adapter, CONSTRUCTOR_OBJECT, writeLog, suppressWSbeforeArg, output), _keys);
    adapter.returnValue();
    adapter.endMethod();

    cw.visitEnd();
    byte[] barr = cw.toByteArray();

    try {
        ResourceUtil.touch(classFile);
        IOUtil.copy(new ByteArrayInputStream(barr), classFile, true);

        cl = (PhysicalClassLoader) ((PageContextImpl) pc).getRPCClassLoader(true);

        return registerTypeMapping(cl.loadClass(className, barr));
    } catch (Throwable t) {
        throw Caster.toPageException(t);
    }
}

From source file:lucee.runtime.type.util.ComponentUtil.java

License:Open Source License

private static int createMethod(BytecodeContext statConstr, BytecodeContext constr,
        java.util.List<LitString> keys, ClassWriter cw, String className, Object member, int max,
        boolean writeLog, boolean suppressWSbeforeArg, boolean output) throws PageException {

    boolean hasOptionalArgs = false;

    if (member instanceof UDF) {
        UDF udf = (UDF) member;//w w  w.  j  av a 2s .c o m
        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);//Type.getType(Caster.cfTypeToClass(args[y].getTypeAsString()));
            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, statConstr, constr, getPage(statConstr, constr), keys,
                cw, className, adapter, method, writeLog, suppressWSbeforeArg, output);
        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(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;
}

From source file:lucee.transformer.bytecode.Page.java

License:Open Source License

/**
 * result byte code as binary array//from w w w.  j  a v a2 s  .  co  m
 * @param classFile 
 * @return byte code
 * @throws IOException 
 * @throws TemplateException 
 */
public byte[] execute(PageSource source, Resource classFile) throws BytecodeException {
    /*
    // this is done that the Page can be executed more than once
    if(initFunctions==null)
       initFunctions=(ArrayList<IFunction>) functions.clone();
    else
       functions=initFunctions;
    if(initThreads==null)
       initThreads=(ArrayList<TagThread>) threads.clone();
    else
       threads=initThreads;
    methodCount=0;
    off=0;
    staticTextLocation=null;
            
            
    print.e(this.functions);
    print.e(this.threads);*/

    Resource p = classFile.getParentResource().getRealResource(classFile.getName() + ".txt");

    List<LitString> keys = new ArrayList<LitString>();
    ClassWriter cw = ASMUtil.getClassWriter();

    ArrayList<String> imports = new ArrayList<String>();
    getImports(imports, this);

    // parent
    String parent = "lucee/runtime/PagePlus";
    if (isComponent())
        parent = "lucee/runtime/ComponentPage";
    else if (isInterface())
        parent = "lucee/runtime/InterfacePage";

    cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, name, null, parent, null);
    cw.visitSource(this.pageSource.getPhyscalFile().getAbsolutePath(),
            "rel:" + this.pageSource.getFullRealpath()); // when adding more use ; as delimiter
    //

    // static constructor
    //GeneratorAdapter statConstrAdapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC,STATIC_CONSTRUCTOR,null,null,cw);
    BytecodeContext statConstr = null;//new BytecodeContext(null,null,this,externalizer,keys,cw,name,statConstrAdapter,STATIC_CONSTRUCTOR,writeLog(),suppressWSbeforeArg);

    // constructor
    GeneratorAdapter constrAdapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC, CONSTRUCTOR_PS, null, null, cw);
    BytecodeContext constr = new BytecodeContext(source, null, null, this, keys, cw, name, constrAdapter,
            CONSTRUCTOR_PS, writeLog(), suppressWSbeforeArg, output);
    constrAdapter.loadThis();
    Type t = Types.PAGE_PLUS;
    if (isComponent())
        t = Types.COMPONENT_PAGE;
    else if (isInterface())
        t = Types.INTERFACE_PAGE;

    constrAdapter.invokeConstructor(t, CONSTRUCTOR);

    // call _init()
    constrAdapter.visitVarInsn(Opcodes.ALOAD, 0);
    constrAdapter.visitMethodInsn(Opcodes.INVOKEVIRTUAL, constr.getClassName(), "initKeys", "()V");

    // private static  ImportDefintion[] test=new ImportDefintion[]{...};
    {
        FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL, "imports",
                "[Llucee/runtime/component/ImportDefintion;", null, null);
        fv.visitEnd();

        constrAdapter.visitVarInsn(Opcodes.ALOAD, 0);
        ArrayVisitor av = new ArrayVisitor();
        av.visitBegin(constrAdapter, Types.IMPORT_DEFINITIONS, imports.size());
        int index = 0;
        Iterator<String> it = imports.iterator();
        while (it.hasNext()) {
            av.visitBeginItem(constrAdapter, index++);
            constrAdapter.push(it.next());
            ASMConstants.NULL(constrAdapter);
            constrAdapter.invokeStatic(Types.IMPORT_DEFINITIONS_IMPL, ID_GET_INSTANCE);
            av.visitEndItem(constrAdapter);
        }
        av.visitEnd();
        constrAdapter.visitFieldInsn(Opcodes.PUTFIELD, name, "imports",
                "[Llucee/runtime/component/ImportDefintion;");

    }

    // getVersion
    GeneratorAdapter adapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, VERSION, null, null,
            cw);
    adapter.push(version);
    adapter.returnValue();
    adapter.endMethod();

    // public ImportDefintion[] getImportDefintions()
    if (imports.size() > 0) {
        adapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, GET_IMPORT_DEFINITIONS, null,
                null, cw);
        adapter.visitVarInsn(Opcodes.ALOAD, 0);
        adapter.visitFieldInsn(Opcodes.GETFIELD, name, "imports", "[Llucee/runtime/component/ImportDefintion;");
        adapter.returnValue();
        adapter.endMethod();
    } else {
        adapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, GET_IMPORT_DEFINITIONS, null,
                null, cw);
        adapter.visitInsn(Opcodes.ICONST_0);
        adapter.visitTypeInsn(Opcodes.ANEWARRAY, "lucee/runtime/component/ImportDefintion");
        adapter.returnValue();
        adapter.endMethod();
    }

    // getSourceLastModified
    adapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, LAST_MOD, null, null, cw);
    adapter.push(lastModifed);
    adapter.returnValue();
    adapter.endMethod();

    // getCompileTime
    adapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, COMPILE_TIME, null, null, cw);
    adapter.push(System.currentTimeMillis());
    adapter.returnValue();
    adapter.endMethod();

    // newInstance/initComponent/call
    if (isComponent()) {
        Tag component = getComponent();
        writeOutNewComponent(statConstr, constr, keys, cw, component);
        writeOutInitComponent(statConstr, constr, keys, cw, component);
    } else if (isInterface()) {
        Tag interf = getInterface();
        writeOutNewInterface(statConstr, constr, keys, cw, interf);
        writeOutInitInterface(statConstr, constr, keys, cw, interf);
    } else {
        writeOutCall(statConstr, constr, keys, cw);
    }

    // udfCall     
    Function[] functions = getFunctions();
    ConditionVisitor cv;
    DecisionIntVisitor div;
    // less/equal than 10 functions
    if (isInterface()) {
    } else if (functions.length <= 10) {
        adapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, UDF_CALL, null,
                new Type[] { Types.THROWABLE }, cw);
        BytecodeContext bc = new BytecodeContext(source, statConstr, constr, this, keys, cw, name, adapter,
                UDF_CALL, writeLog(), suppressWSbeforeArg, output);
        if (functions.length == 0) {
        } else if (functions.length == 1) {
            ExpressionUtil.visitLine(bc, functions[0].getStart());
            functions[0].getBody().writeOut(bc);
            ExpressionUtil.visitLine(bc, functions[0].getEnd());
        } else
            writeOutUdfCallInner(bc, functions, 0, functions.length);
        adapter.visitInsn(Opcodes.ACONST_NULL);
        adapter.returnValue();
        adapter.endMethod();
    }
    // more than 10 functions
    else {
        adapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, UDF_CALL, null,
                new Type[] { Types.THROWABLE }, cw);
        BytecodeContext bc = new BytecodeContext(source, statConstr, constr, this, keys, cw, name, adapter,
                UDF_CALL, writeLog(), suppressWSbeforeArg, output);
        cv = new ConditionVisitor();
        cv.visitBefore();
        int count = 0;
        for (int i = 0; i < functions.length; i += 10) {
            cv.visitWhenBeforeExpr();
            div = new DecisionIntVisitor();
            div.visitBegin();
            adapter.loadArg(2);
            div.visitLT();
            adapter.push(i + 10);
            div.visitEnd(bc);
            cv.visitWhenAfterExprBeforeBody(bc);

            adapter.visitVarInsn(Opcodes.ALOAD, 0);
            adapter.visitVarInsn(Opcodes.ALOAD, 1);
            adapter.visitVarInsn(Opcodes.ALOAD, 2);
            adapter.visitVarInsn(Opcodes.ILOAD, 3);
            adapter.visitMethodInsn(Opcodes.INVOKEVIRTUAL, name, createFunctionName(++count),
                    "(Llucee/runtime/PageContext;Llucee/runtime/type/UDF;I)Ljava/lang/Object;");
            adapter.visitInsn(Opcodes.ARETURN);//adapter.returnValue();
            cv.visitWhenAfterBody(bc);
        }
        cv.visitAfter(bc);

        adapter.visitInsn(Opcodes.ACONST_NULL);
        adapter.returnValue();
        adapter.endMethod();

        count = 0;
        Method innerCall;
        for (int i = 0; i < functions.length; i += 10) {
            innerCall = new Method(createFunctionName(++count), Types.OBJECT,
                    new Type[] { Types.PAGE_CONTEXT, USER_DEFINED_FUNCTION, Types.INT_VALUE });

            adapter = new GeneratorAdapter(Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL, innerCall, null,
                    new Type[] { Types.THROWABLE }, cw);
            writeOutUdfCallInner(
                    new BytecodeContext(source, statConstr, constr, this, keys, cw, name, adapter, innerCall,
                            writeLog(), suppressWSbeforeArg, output),
                    functions, i, i + 10 > functions.length ? functions.length : i + 10);

            adapter.visitInsn(Opcodes.ACONST_NULL);
            adapter.returnValue();
            adapter.endMethod();
        }
    }

    // threadCall
    TagThread[] threads = getThreads();
    if (true) {
        adapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, THREAD_CALL, null,
                new Type[] { Types.THROWABLE }, cw);
        if (threads.length > 0)
            writeOutThreadCallInner(new BytecodeContext(source, statConstr, constr, this, keys, cw, name,
                    adapter, THREAD_CALL, writeLog(), suppressWSbeforeArg, output), threads, 0, threads.length);
        //adapter.visitInsn(Opcodes.ACONST_NULL);
        adapter.returnValue();
        adapter.endMethod();
    }

    // udfDefaultValue
    // less/equal than 10 functions
    if (isInterface()) {
    } else if (functions.length <= 10) {
        adapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, UDF_DEFAULT_VALUE, null,
                new Type[] { Types.PAGE_EXCEPTION }, cw);
        if (functions.length > 0)
            writeUdfDefaultValueInner(
                    new BytecodeContext(source, statConstr, constr, this, keys, cw, name, adapter,
                            UDF_DEFAULT_VALUE, writeLog(), suppressWSbeforeArg, output),
                    functions, 0, functions.length);

        adapter.loadArg(DEFAULT_VALUE);
        adapter.returnValue();
        adapter.endMethod();
    } else {
        adapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, UDF_DEFAULT_VALUE, null,
                new Type[] { Types.PAGE_EXCEPTION }, cw);
        BytecodeContext bc = new BytecodeContext(source, statConstr, constr, this, keys, cw, name, adapter,
                UDF_DEFAULT_VALUE, writeLog(), suppressWSbeforeArg, output);
        cv = new ConditionVisitor();
        cv.visitBefore();
        int count = 0;
        for (int i = 0; i < functions.length; i += 10) {
            cv.visitWhenBeforeExpr();
            div = new DecisionIntVisitor();
            div.visitBegin();
            adapter.loadArg(1);
            div.visitLT();
            adapter.push(i + 10);
            div.visitEnd(bc);
            cv.visitWhenAfterExprBeforeBody(bc);

            adapter.visitVarInsn(Opcodes.ALOAD, 0);
            adapter.visitVarInsn(Opcodes.ALOAD, 1);
            adapter.visitVarInsn(Opcodes.ILOAD, 2);
            adapter.visitVarInsn(Opcodes.ILOAD, 3);
            adapter.visitVarInsn(Opcodes.ALOAD, 4);

            adapter.visitMethodInsn(Opcodes.INVOKEVIRTUAL, name, "udfDefaultValue" + (++count),
                    "(Llucee/runtime/PageContext;IILjava/lang/Object;)Ljava/lang/Object;");
            adapter.visitInsn(Opcodes.ARETURN);//adapter.returnValue();

            cv.visitWhenAfterBody(bc);
        }
        cv.visitAfter(bc);

        adapter.visitInsn(Opcodes.ACONST_NULL);
        adapter.returnValue();
        adapter.endMethod();

        count = 0;
        Method innerDefaultValue;
        for (int i = 0; i < functions.length; i += 10) {
            innerDefaultValue = new Method("udfDefaultValue" + (++count), Types.OBJECT,
                    new Type[] { Types.PAGE_CONTEXT, Types.INT_VALUE, Types.INT_VALUE, Types.OBJECT });
            adapter = new GeneratorAdapter(Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL, innerDefaultValue, null,
                    new Type[] { Types.PAGE_EXCEPTION }, cw);
            writeUdfDefaultValueInner(
                    new BytecodeContext(source, statConstr, constr, this, keys, cw, name, adapter,
                            innerDefaultValue, writeLog(), suppressWSbeforeArg, output),
                    functions, i, i + 10 > functions.length ? functions.length : i + 10);

            adapter.loadArg(DEFAULT_VALUE);
            //adapter.visitInsn(Opcodes.ACONST_NULL);
            adapter.returnValue();
            adapter.endMethod();
        }

    }

    // register fields
    {
        GeneratorAdapter aInit = new GeneratorAdapter(Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL, _INIT, null,
                null, cw);
        BytecodeContext bcInit = new BytecodeContext(source, statConstr, constr, this, keys, cw, name, aInit,
                _INIT, writeLog(), suppressWSbeforeArg, output);
        registerFields(bcInit, keys);
        aInit.returnValue();
        aInit.endMethod();
    }

    //setPageSource(pageSource);
    constrAdapter.visitVarInsn(Opcodes.ALOAD, 0);
    constrAdapter.visitVarInsn(Opcodes.ALOAD, 1);
    constrAdapter.invokeVirtual(t, SET_PAGE_SOURCE);

    constrAdapter.returnValue();
    constrAdapter.endMethod();

    return cw.toByteArray();

}