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

scouter.javassist.expr.Instanceof Maven / Gradle / Ivy

There is a newer version: 2.20.0
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 scouter.javassist.expr;

import static scouter.javassist.expr.Expr.checkResultValue;
import static scouter.javassist.expr.Expr.javaLangObject;
import static scouter.javassist.expr.Expr.storeStack;
import scouter.javassist.CannotCompileException;
import scouter.javassist.ClassPool;
import scouter.javassist.CtBehavior;
import scouter.javassist.CtClass;
import scouter.javassist.NotFoundException;
import scouter.javassist.bytecode.BadBytecode;
import scouter.javassist.bytecode.Bytecode;
import scouter.javassist.bytecode.CodeAttribute;
import scouter.javassist.bytecode.CodeIterator;
import scouter.javassist.bytecode.ConstPool;
import scouter.javassist.bytecode.MethodInfo;
import scouter.javassist.bytecode.Opcode;
import scouter.javassist.compiler.CompileError;
import scouter.javassist.compiler.Javac;
import scouter.javassist.compiler.JvstCodeGen;
import scouter.javassist.compiler.JvstTypeChecker;
import scouter.javassist.compiler.ProceedHandler;
import scouter.javassist.compiler.ast.ASTList;
import scouter.javassist.expr.Expr;

/**
 * Instanceof operator.
 */
public class Instanceof extends Expr {
    /**
     * Undocumented constructor.  Do not use; internal-use only.
     */
    protected Instanceof(int pos, CodeIterator i, CtClass declaring,
                         MethodInfo m) {
        super(pos, i, declaring, m);
    }

    /**
     * Returns the method or constructor containing the instanceof
     * expression represented by this object.
     */
    public CtBehavior where() { return super.where(); }

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

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

    /**
     * Returns the CtClass object representing
     * the type name on the right hand side
     * of the instanceof operator.
     */
    public CtClass getType() throws NotFoundException {
        ConstPool cp = getConstPool();
        int pos = currentPos;
        int index = iterator.u16bitAt(pos + 1);
        String name = cp.getClassInfo(index);
        return thisClass.getClassPool().getCtClass(name);
    }

    /**
     * Returns the list of exceptions that the expression may throw.
     * This list includes both the exceptions that the try-catch statements
     * including the expression can catch and the exceptions that
     * the throws declaration allows the method to throw.
     */
    public CtClass[] mayThrow() {
        return super.mayThrow();
    }

    /**
     * Replaces the instanceof operator with the bytecode derived from
     * the given source text.
     *
     * 

$0 is available but the value is null. * * @param statement a Java statement except try-catch. */ public void replace(String statement) throws CannotCompileException { thisClass.getClassFile(); // to call checkModify(). ConstPool constPool = getConstPool(); int pos = currentPos; int index = iterator.u16bitAt(pos + 1); Javac jc = new Javac(thisClass); ClassPool cp = thisClass.getClassPool(); CodeAttribute ca = iterator.get(); try { CtClass[] params = new CtClass[] { cp.get(javaLangObject) }; CtClass retType = CtClass.booleanType; int paramVar = ca.getMaxLocals(); jc.recordParams(javaLangObject, params, true, paramVar, withinStatic()); int retVar = jc.recordReturnType(retType, true); jc.recordProceed(new ProceedForInstanceof(index)); // because $type is not the return type... jc.recordType(getType()); /* Is $_ included in the source code? */ checkResultValue(retType, statement); Bytecode bytecode = jc.getBytecode(); storeStack(params, true, paramVar, bytecode); jc.recordLocalVariables(ca, pos); bytecode.addConstZero(retType); bytecode.addStore(retVar, retType); // initialize $_ jc.compileStmnt(statement); bytecode.addLoad(retVar, retType); replace0(pos, bytecode, 3); } catch (CompileError e) { throw new CannotCompileException(e); } catch (NotFoundException e) { throw new CannotCompileException(e); } catch (BadBytecode e) { throw new CannotCompileException("broken method"); } } /* boolean $proceed(Object obj) */ static class ProceedForInstanceof implements ProceedHandler { int index; ProceedForInstanceof(int i) { index = i; } public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args) throws CompileError { if (gen.getMethodArgsLength(args) != 1) throw new CompileError(Javac.proceedName + "() cannot take more than one parameter " + "for instanceof"); gen.atMethodArgs(args, new int[1], new int[1], new String[1]); bytecode.addOpcode(Opcode.INSTANCEOF); bytecode.addIndex(index); gen.setType(CtClass.booleanType); } public void setReturnType(JvstTypeChecker c, ASTList args) throws CompileError { c.atMethodArgs(args, new int[1], new int[1], new String[1]); c.setType(CtClass.booleanType); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy