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

gnu.jel.OPcall Maven / Gradle / Ivy

There is a newer version: 0.8.1
Show newest version
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- 
 * $Id: OPcall.java 490 2006-10-01 16:08:04Z metlov $
 *
 * This file is part of the Java Expressions Library (JEL).
 *   For more information about JEL visit :
 *    http://kinetic.ac.donetsk.ua/JEL/
 *
 * (c) 1998 -- 2007 by Konstantin Metlov([email protected]);
 *
 * JEL is Distributed under the terms of GNU General Public License.
 *    This code comes with ABSOLUTELY NO WARRANTY.
 *  For license details see COPYING file in this directory.
 */

package gnu.jel;

import java.lang.reflect.Member;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import gnu.jel.debug.Debug;
import java.util.Stack;

/**
 * A tree node, representing a method call (field/local variable load).
 */
public class OPcall extends OP {

  /** Holds method to be executed */
  public Member m; // member to eval (null for the local variable access)

  /**
   * local variable number (in case m=null), number of formal
   * parameters of the method to call otherwise.  */
  public int nplv=0;

  /**
   * if evaluation of the method will be attempted at compile-time */
  private boolean aEval=false;

  /**
   * Prepares a new method/field call/get operation to be added to the code.
   * @param paramOPs stack holding the operands
   * @param m method/field to call/get.
   * @param aEval indicates if the method call should be attempted
   *                    at the compile time
   */
  public OPcall(Stack paramOPs, Member m, boolean aEval) 
    throws CompilationException {
    this.m=m;
    
    Class[] reqParamTypes=Library.getParameterTypes(m);
    nplv=reqParamTypes.length;
    
    int thisIdx=0;
    if ((m.getModifiers() & 0x0008) == 0) { // method is not static
      thisIdx=-1;
      nplv++;
    };

    this.chi=new OP[nplv];

    // convert formal and actual parameter types and "this", if needed    
    for(int i=reqParamTypes.length-1;i>=thisIdx;i--) {
      Class cReq=(i>=0?reqParamTypes[i]:m.getDeclaringClass());

      OP cop=(OP)paramOPs.peek();

      // add convert type OP
      if ((cop.resID==10) || (cop.resType!=cReq))
        paramOPs.push(new OPunary(paramOPs,typeID(cReq),cReq,i<0));

      chi[i-thisIdx]=(OP)paramOPs.pop();
    };
    
    // push & store the result type
    resType=Library.getType(m);
    resID=typeID(resType);
    //    System.out.println("MAKING CALL TO "+m.getName()+
    //                       ClassFile.getSignature(m)+" returning "+
    //                       m.getType());

    // determine if compile-time evaluation should be attempted
    this.aEval=(aEval &&  // eval only if requested.
                ((m.getModifiers() & 0x0008)!=0) && // if static
                ((resID<=7) || (resID==11)) //  if can store result
                );
  };

  /**
   * Prepares access to the local variable (formal parameter) of method.
   * @param lvarn local variable number.
   * @param type local variable type.
   */
  public OPcall(int lvarn, Class type) {
    this.m=null;
    this.nplv=lvarn;
    resID=typeID(type);
    resType=type;
  };

  /**
   * Attempts to evaluate this function.
   * @return the OPload, representing the function's result (if it can \
   *         be evaluated).
   * @throws Exception if the function can't be evaluated, or the evaluation
   *         results in error.
   */
  public Object eval() throws Exception {
    Object[] params=new Object[chi.length];
    boolean[] evaltd=new boolean[chi.length];
    
    Exception exception=null;
    for(int i=0;i




© 2015 - 2024 Weber Informatics LLC | Privacy Policy