/** * 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); }
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); }