| 3726 | } |
| 3727 | |
| 3728 | unsigned SelectBestFunction(unsigned count, unsigned callArgCount, unsigned int &minRating, TypeInfo* forcedParentType) |
| 3729 | { |
| 3730 | // Find the best suited function |
| 3731 | bestFuncRating.resize(count); |
| 3732 | |
| 3733 | unsigned int minGenericRating = ~0u; |
| 3734 | unsigned int minRatingIndex = ~0u, minGenericIndex = ~0u; |
| 3735 | for(unsigned int k = 0; k < count; k++) |
| 3736 | { |
| 3737 | unsigned int argumentCount = callArgCount; |
| 3738 | // Act as if default parameter values were passed |
| 3739 | if(argumentCount < bestFuncList[k]->paramCount) |
| 3740 | { |
| 3741 | // Move to the last parameter |
| 3742 | VariableInfo *param = bestFuncList[k]->firstParam; |
| 3743 | for(unsigned int i = 0; i < argumentCount; i++) |
| 3744 | param = param->next; |
| 3745 | // While there are default values, put them |
| 3746 | while(param && param->defaultValue) |
| 3747 | { |
| 3748 | argumentCount++; |
| 3749 | CodeInfo::nodeList.push_back(param->defaultValue); |
| 3750 | param = param->next; |
| 3751 | } |
| 3752 | } |
| 3753 | if(argumentCount >= (bestFuncList[k]->paramCount - 1) && bestFuncList[k]->lastParam && bestFuncList[k]->lastParam->varType == typeObjectArray && |
| 3754 | !(argumentCount == bestFuncList[k]->paramCount && CodeInfo::nodeList.back()->typeInfo == typeObjectArray)) |
| 3755 | { |
| 3756 | // If function accepts variable argument list |
| 3757 | TypeInfo *&lastType = bestFuncList[k]->funcType->funcType->paramType[bestFuncList[k]->paramCount - 1]; |
| 3758 | assert(lastType == CodeInfo::GetArrayType(typeObject, TypeInfo::UNSIZED_ARRAY)); |
| 3759 | unsigned int redundant = argumentCount - bestFuncList[k]->paramCount; |
| 3760 | if(redundant == ~0u) |
| 3761 | CodeInfo::nodeList.push_back(new NodeZeroOP(typeObjectArray)); |
| 3762 | else |
| 3763 | CodeInfo::nodeList.shrink(CodeInfo::nodeList.size() - redundant); |
| 3764 | // Change things in a way that this function will be selected (lie about real argument count and match last argument type) |
| 3765 | lastType = CodeInfo::nodeList.back()->typeInfo; |
| 3766 | bestFuncRating[k] = GetFunctionRating(bestFuncList[k]->funcType->funcType, bestFuncList[k]->paramCount); |
| 3767 | if(redundant == ~0u) |
| 3768 | CodeInfo::nodeList.pop_back(); |
| 3769 | else |
| 3770 | CodeInfo::nodeList.resize(CodeInfo::nodeList.size() + redundant); |
| 3771 | if(bestFuncRating[k] != ~0u) |
| 3772 | bestFuncRating[k] += 10 + (redundant == ~0u ? 5 : redundant * 5); // Cost of variable arguments function |
| 3773 | lastType = CodeInfo::GetArrayType(typeObject, TypeInfo::UNSIZED_ARRAY); |
| 3774 | }else{ |
| 3775 | bestFuncRating[k] = GetFunctionRating(bestFuncList[k]->funcType->funcType, argumentCount); |
| 3776 | } |
| 3777 | if(bestFuncList[k]->generic) |
| 3778 | { |
| 3779 | // If we have a positive rating, check that generic function constraints are satisfied |
| 3780 | if(bestFuncRating[k] != ~0u) |
| 3781 | { |
| 3782 | unsigned newRating = bestFuncRating[k]; |
| 3783 | TypeInfo *parentClass = bestFuncList[k]->parentClass; |
| 3784 | if(forcedParentType && bestFuncList[k]->parentClass != forcedParentType) |
| 3785 | { |
no test coverage detected