/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- 
 * $Id: Method.java,v 1.2 2000/09/09 19:51:48 metlov Exp $
 *
 * This file is part of the Java Expressions Library (JEL).
 *   For more information about JEL visit :
 *    http://galaxy.fzu.cz/JEL/
 *
 * (c) 1998 -- 2000 by Konstantin Metlov(metlov@fzu.cz);
 *
 * 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.reflect;

import gnu.jel.debug.Debug;

/**
 * Represents a method of already compiled class.
 */
public class Method extends LocalMethod {
  Class declClass;
  java.lang.reflect.Method m;
  
  /**
   * Constructs a new Method object.
   * @param m is corresponding <TT>java.lang.reflect.Method</TT> object.
   */   
  public Method(java.lang.reflect.Method m) {
	super(m.getModifiers(),m.getReturnType(),m.getName(),
	      m.getParameterTypes(),m.getExceptionTypes());
    this.m=m;
    declClass=m.getDeclaringClass();
    modifiers=modifiers & 0x0000FFFF; // clears field mark
    if (declClass.isInterface())
      modifiers=modifiers | 0x00040000;
  };

  /**
   * Constructs a new Method object for a constructor.
   * @param m is corresponding <TT>java.lang.reflect.Method</TT> object.
   */
  public Method(java.lang.reflect.Constructor c) {
	super(c.getModifiers(),Void.TYPE,"<init>",
	      c.getParameterTypes(),c.getExceptionTypes());
    modifiers=(modifiers & 0x0000FFFF) | 0x00020000;
    declClass=c.getDeclaringClass();
    if (declClass.isInterface())
      modifiers=modifiers | 0x00040000;
  };

  public Class getDeclaringClass() {
	return declClass;
  };

  public Object eval(Object obj,Object[] params) throws Exception {
	return m.invoke(obj,params);
  };

  /**
   * Generates the code for loading this field to stack.
   * <P>For field/variable invoke means to get value. No type checks are
   * performed.
   * @param cf classfile to append instructions to.
   */
  public void code(gnu.jel.ClassFile cf) {
    int cfID=10;
    if ((modifiers & 0x00030000)>0) {    // constructor ?
      cf.code(0xb7);                     //         |  invokespecial
      cfID++;
    } else if ((modifiers & 0x0008)>0)   // static ?
      cf.code(0xb8);                     //         |  invokestatic
    else if ((modifiers & 0x00040000)>0) // declared in interface ?
      cf.code(0xb9);                     //         |  invokeinterface
    else
      cf.code(0xb6);                     //         |  invokevirtual
    
    cf.codeI(cf.getIndex(this,cfID));  //         |  <CP index>

    if ((modifiers & 0x00040000)>0) {    // declared in interface ?
      cf.codeI((1+m.getParameterTypes().length)<<8); //|  <nargs> 0
    };
  };

};






