/**
         * Evaluates the function.
         */
        public override Value callMethod(Env env, QuercusClass qClass, Value qThis,
                                         Value [] args)
        {
            if (args.length < _methodTable.length)
            {
                AbstractJavaMethod [] methods = _methodTable[args.length];

                if (methods != null)
                {
                    if (methods.length == 1)
                    {
                        return(methods[0].callMethod(env, qClass, qThis, args));
                    }
                    else
                    {
                        AbstractJavaMethod method
                            = getBestFitJavaMethod(methods, _restMethodTable, args);

                        return(method.callMethod(env, qClass, qThis, args));
                    }
                }
                else
                {
                    if (_restMethodTable.length == 0)
                    {
                        env.warning(L.l(
                                        "'{0}' overloaded method call with {1} arguments "
                                        + "does not match any overloaded method",
                                        getName(),
                                        args.length));

                        return(NullValue.NULL);
                    }

                    AbstractJavaMethod method
                        = getBestFitJavaMethod(methods, _restMethodTable, args);

                    return(method.callMethod(env, qClass, qThis, args));
                }
            }
            else
            {
                if (_restMethodTable.length == 0)
                {
                    env.warning(L.l(
                                    "'{0}' overloaded method call with {1} "
                                    + "arguments has too many arguments", getName(), args.length));

                    return(NullValue.NULL);
                }
                else
                {
                    AbstractJavaMethod method
                        = getBestFitJavaMethod(null, _restMethodTable, args);

                    return(method.callMethod(env, qClass, qThis, args));
                }
            }
        }
        getBestFitJavaMethod(AbstractJavaMethod [] methods,
                             AbstractJavaMethod [][] restMethodTable,
                             Expr [] args)
        {
            AbstractJavaMethod minCostJavaMethod = null;
            int minCost = Integer.MAX_VALUE;

            if (methods != null)
            {
                for (int i = 0; i < methods.length; i++)
                {
                    AbstractJavaMethod javaMethod = methods[i];

                    int cost = javaMethod.getMarshalingCost(args);

                    if (cost == 0)
                    {
                        return(javaMethod);
                    }

                    if (cost <= minCost)
                    {
                        minCost           = cost;
                        minCostJavaMethod = javaMethod;
                    }
                }
            }

            for (int i = Math.min(args.length, restMethodTable.length) - 1;
                 i >= 0;
                 i--)
            {
                if (restMethodTable[i] == null)
                {
                    continue;
                }

                for (int j = 0; j < restMethodTable[i].length; j++)
                {
                    AbstractJavaMethod javaMethod = restMethodTable[i][j];

                    int cost = javaMethod.getMarshalingCost(args);

                    if (cost == 0)
                    {
                        return(javaMethod);
                    }

                    if (cost <= minCost)
                    {
                        minCost           = cost;
                        minCostJavaMethod = javaMethod;
                    }
                }
            }

            return(minCostJavaMethod);
        }
示例#3
0
        public void addFunction(String name, AbstractJavaMethod fun)
        {
            AbstractJavaMethod oldFun = _funMap.get(name);

            if (oldFun == null)
            {
                _funMap.put(name, fun);
            }
            else
            {
                _funMap.put(name, oldFun.overload(fun));
            }
        }
        /**
         * Returns the cost of marshaling for this method given the args.
         */
        public int getMarshalingCost(Value [] args)
        {
            AbstractJavaMethod [] methods = null;

            if (args.length < _methodTable.length)
            {
                methods = _methodTable[args.length];
            }

            AbstractJavaMethod bestFitMethod
                = getBestFitJavaMethod(methods, _restMethodTable, args);

            return(bestFitMethod.getMarshalingCost(args));
        }
        /**
         * Returns an overloaded java method.
         */
        public AbstractJavaMethod overload(AbstractJavaMethod fun)
        {
            if (fun.getHasRestArgs())
            {
                int len = fun.getMinArgLength();

                if (_restMethodTable.length <= len)
                {
                    AbstractJavaMethod [][] restMethodTable
                        = new AbstractJavaMethod[len + 1][];

                    System.arraycopy(_restMethodTable, 0,
                                     restMethodTable, 0, _restMethodTable.length);

                    _restMethodTable = restMethodTable;
                }

                AbstractJavaMethod [] methods = _restMethodTable[len];

                if (methods == null)
                {
                    _restMethodTable[len] = new AbstractJavaMethod[] { fun }
                }
                ;
                else
                {
                    AbstractJavaMethod [] newMethods
                        = new AbstractJavaMethod[methods.length + 1];

                    System.arraycopy(methods, 0, newMethods, 0, methods.length);

                    newMethods[methods.length] = fun;

                    _restMethodTable[len] = newMethods;
                }
            }
            else
            {
                int maxLen = fun.getMaxArgLength();

                if (_methodTable.length <= maxLen)
                {
                    AbstractJavaMethod [][] methodTable
                        = new AbstractJavaMethod[maxLen + 1][];

                    System.arraycopy(_methodTable, 0, methodTable, 0, _methodTable.length);

                    _methodTable = methodTable;
                }

                for (int len = fun.getMinArgLength(); len <= maxLen; len++)
                {
                    AbstractJavaMethod [] methods = _methodTable[len];

                    if (methods == null)
                    {
                        _methodTable[len] = new AbstractJavaMethod[] { fun }
                    }
                    ;
                    else
                    {
                        AbstractJavaMethod [] newMethods
                            = new AbstractJavaMethod[methods.length + 1];

                        System.arraycopy(methods, 0, newMethods, 0, methods.length);

                        newMethods[methods.length] = fun;

                        _methodTable[len] = newMethods;
                    }
                }
            }

            return(this);
        }
 public JavaOverloadMethod(AbstractJavaMethod fun)
 {
     overload(fun);
 }