/*
* $Id: FunctionBase.java,v 1.3 2002/09/16 08:05:04 jkl Exp $
*
* Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
*
* Use is subject to license terms, as defined in
* Anvil Sofware License, Version 1.1. See LICENSE
* file, or http://njet.org/license-1.1.txt
*/
package anvil.script.compiler;
import java.util.HashMap;
import anvil.core.Any;
import anvil.core.AnyTuple;
import anvil.core.ObjectPool;
import anvil.codec.ConstantPool;
import anvil.doc.Doc;
import anvil.script.CompilableFunction;
import anvil.script.FunctionDispatcher;
import anvil.script.GeneratorDispatcher;
import anvil.script.Context;
import anvil.script.Type;
import anvil.script.ExitException;
import anvil.script.ParameterListDeclaration;
import anvil.script.ScriptException;
import anvil.script.Scope;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/**
* class FunctionBase
*
* @author: Jani Lehtim�ki
*/
public class FunctionBase extends Compiled implements CompilableFunction
{
protected String _functionname;
protected Method _method;
protected boolean _isinner;
protected FunctionDispatcher _dispatcher;
protected GeneratorDispatcher _generatordispatcher;
protected ParameterListDeclaration _parameters;
protected HashMap _define = null;
public FunctionBase(Scope parent, Method method, String name, Object[] parameters, Doc document)
{
super(parent, name, document);
_method = method;
_functionname = method.getName();
_parameters = new ParameterListDeclaration(method, parameters, document);
_isinner = (name.indexOf('$')>=0);
if (document != null) {
Doc[] defines = document.find(Doc.T_DEFINE, null);
int n = defines.length;
if (n>0) {
_define = new HashMap();
for(int i=0; i<n; i++) {
Doc doc = defines[i];
_define.put(doc.getIdent(), Any.create(doc.getText()));
}
}
}
}
public String toString()
{
StringBuffer buffer = new StringBuffer(40);
super.toString(buffer);
buffer.append('(');
_parameters.toString(buffer);
buffer.append(')');
return buffer.toString();
}
public int getType()
{
return FUNCTION;
}
public int getMinimumParameterCount()
{
return _parameters.minSize();
}
public int getParameterCount()
{
return _parameters.size();
}
public String getParameterName(int index)
{
return _parameters.getName(index);
}
public int getParameterType(int index)
{
return _parameters.getType(index);
}
public Any getParameterDefault(int index)
{
return _parameters.getDefault(index);
}
public Doc getParameterDoc(int index)
{
return _parameters.getDoc(index);
}
public boolean isInnerFunction()
{
return _isinner;
}
public FunctionDispatcher getDispatcher(Context context)
{
FunctionDispatcher dispatcher = _dispatcher;
if (dispatcher == null) {
synchronized(this) {
if (_dispatcher != null) {
return _dispatcher;
}
try {
_dispatcher = dispatcher = DispatcherFactory.create(
this, Modifier.isStatic(_method.getModifiers()), context.zone().getClassLoader());
} catch (LinkageError e) {
context.log().error("FunctionBase.getDispatcher(" + this + ")", e);
throw context.InternalError("Creation of dispatcher failed: "+e);
} catch (Throwable t) {
context.log().error("FunctionBase.getDispatcher(" + this + ")", t);
throw context.InternalError(t.toString());
}
}
}
return dispatcher;
}
public Any execute(Context context, Any[] parameters)
{
return execute(context, (Any)null, parameters);
}
public Any execute(Context context, Any self, Any[] parameters)
{
return getDispatcher(context).execute(context, self, parameters);
}
public Any execute(Context context, Any self)
{
return getDispatcher(context).execute(context, self);
}
public Any execute(Context context, Any self, Any param1)
{
return getDispatcher(context).execute(context, self, param1);
}
public Any execute(Context context, Any self, Any param1, Any param2)
{
return getDispatcher(context).execute(context, self, param1, param2);
}
public Any execute(Context context, Any self, Any param1, Any param2, Any param3)
{
return getDispatcher(context).execute(context, self, param1, param2, param3);
}
public Any execute(Context context, Any self, Any param1, Any param2, Any param3, Any param4)
{
return getDispatcher(context).execute(context, self, param1, param2, param3, param4);
}
public Any getAttribute(String name)
{
if (_define != null) {
return (Any)_define.get(name);
}
return null;
}
public int getTypeRef(anvil.codec.ConstantPool pool)
{
return pool.addMethodRef(_parent.getTypeRef(pool), _functionname, ByteCompiler.getSignature(this));
}
public GeneratorDispatcher getGeneratorDispatcher(Context context)
{
if (_generatordispatcher == null) {
try {
return _generatordispatcher = DispatcherFactory.createGenerator(
this, context.zone().getClassLoader());
} catch (LinkageError e) {
context.log().error("FunctionBase.getGeneratorDispatcher(" + this + ")", e);
throw context.InternalError("Creation of dispatcher failed: "+e);
} catch (Throwable t) {
context.log().error("FunctionBase.getGeneratorDispatcher(" + this + ")", t);
throw context.InternalError(t.toString());
}
}
return _generatordispatcher;
}
}