All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.feilong.lib.javassist.expr.Handler Maven / Gradle / Ivy

Go to download

feilong is a suite of core and expanded libraries that include utility classes, http, excel,cvs, io classes, and much much more.

There is a newer version: 4.0.8
Show newest version
/*
 * Javassist, a Java-bytecode translator toolkit.
 * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License.  Alternatively, the contents of this file may be used under
 * the terms of the GNU Lesser General Public License Version 2.1 or later,
 * or the Apache License Version 2.0.
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 */

package com.feilong.lib.javassist.expr;

import com.feilong.lib.javassist.CannotCompileException;
import com.feilong.lib.javassist.CtBehavior;
import com.feilong.lib.javassist.CtClass;
import com.feilong.lib.javassist.NotFoundException;
import com.feilong.lib.javassist.bytecode.Bytecode;
import com.feilong.lib.javassist.bytecode.CodeAttribute;
import com.feilong.lib.javassist.bytecode.CodeIterator;
import com.feilong.lib.javassist.bytecode.ConstPool;
import com.feilong.lib.javassist.bytecode.ExceptionTable;
import com.feilong.lib.javassist.bytecode.MethodInfo;
import com.feilong.lib.javassist.bytecode.Opcode;
import com.feilong.lib.javassist.compiler.CompileError;
import com.feilong.lib.javassist.compiler.Javac;

/**
 * A catch clause or a finally block.
 */
public class Handler extends Expr{

    private static String  EXCEPTION_NAME = "$1";

    private ExceptionTable etable;

    private int            index;

    /**
     * Undocumented constructor. Do not use; internal-use only.
     */
    protected Handler(ExceptionTable et, int nth, CodeIterator it, CtClass declaring, MethodInfo m){
        super(et.handlerPc(nth), it, declaring, m);
        etable = et;
        index = nth;
    }

    /**
     * Returns the method or constructor containing the catch clause.
     */
    @Override
    public CtBehavior where(){
        return super.where();
    }

    /**
     * Returns the source line number of the catch clause.
     *
     * @return -1 if this information is not available.
     */
    @Override
    public int getLineNumber(){
        return super.getLineNumber();
    }

    /**
     * Returns the source file containing the catch clause.
     *
     * @return null if this information is not available.
     */
    @Override
    public String getFileName(){
        return super.getFileName();
    }

    /**
     * Returns the list of exceptions that the catch clause may throw.
     */
    @Override
    public CtClass[] mayThrow(){
        return super.mayThrow();
    }

    /**
     * Returns the type handled by the catch clause.
     * If this is a finally block, null is returned.
     */
    public CtClass getType() throws NotFoundException{
        int type = etable.catchType(index);
        if (type == 0){
            return null;
        }
        ConstPool cp = getConstPool();
        String name = cp.getClassInfo(type);
        return thisClass.getClassPool().getCtClass(name);
    }

    /**
     * Returns true if this is a finally block.
     */
    public boolean isFinally(){
        return etable.catchType(index) == 0;
    }

    /**
     * This method has not been implemented yet.
     *
     * @param statement
     *            a Java statement except try-catch.
     */
    @Override
    public void replace(String statement) throws CannotCompileException{
        throw new RuntimeException("not implemented yet");
    }

    /**
     * Inserts bytecode at the beginning of the catch clause.
     * The caught exception is stored in $1.
     *
     * @param src
     *            the source code representing the inserted bytecode.
     *            It must be a single statement or block.
     */
    public void insertBefore(String src) throws CannotCompileException{
        edited = true;

        @SuppressWarnings("unused")
        ConstPool cp = getConstPool();
        CodeAttribute ca = iterator.get();
        Javac jv = new Javac(thisClass);
        Bytecode b = jv.getBytecode();
        b.setStackDepth(1);
        b.setMaxLocals(ca.getMaxLocals());

        try{
            CtClass type = getType();
            int var = jv.recordVariable(type, EXCEPTION_NAME);
            jv.recordReturnType(type, false);
            b.addAstore(var);
            jv.compileStmnt(src);
            b.addAload(var);

            int oldHandler = etable.handlerPc(index);
            b.addOpcode(Opcode.GOTO);
            b.addIndex(oldHandler - iterator.getCodeLength() - b.currentPc() + 1);

            maxStack = b.getMaxStack();
            maxLocals = b.getMaxLocals();

            int pos = iterator.append(b.get());
            iterator.append(b.getExceptionTable(), pos);
            etable.setHandlerPc(index, pos);
        }catch (NotFoundException e){
            throw new CannotCompileException(e);
        }catch (CompileError e){
            throw new CannotCompileException(e);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy