| 3185 | } |
| 3186 | |
| 3187 | int asCScriptEngine::GetTemplateFunctionInstance(asCScriptFunction* baseFunc, const asCArray<asCDataType>& types) |
| 3188 | { |
| 3189 | // Check if the template function instance already exists |
| 3190 | // TODO: optimize look up. Build a hash of the baseFunc pointer and types, then store the lookup in a asCMap |
| 3191 | for (asUINT n = 0; n < generatedTemplateFunctionInstances.GetLength(); n++) |
| 3192 | { |
| 3193 | asCScriptFunction* func = generatedTemplateFunctionInstances[n]; |
| 3194 | if (func == 0) continue; |
| 3195 | |
| 3196 | if (func->name == baseFunc->name && |
| 3197 | func->nameSpace == baseFunc->nameSpace && |
| 3198 | func->objectType == baseFunc->objectType && |
| 3199 | func->templateSubTypes == types) |
| 3200 | return func->id; |
| 3201 | } |
| 3202 | |
| 3203 | // Generate the new template function instance |
| 3204 | asCScriptFunction* newFunc = asNEW(asCScriptFunction)(this, 0, baseFunc->funcType); |
| 3205 | if (newFunc == 0) |
| 3206 | return asOUT_OF_MEMORY; |
| 3207 | |
| 3208 | newFunc->name = baseFunc->name; |
| 3209 | for (asUINT n = 0; n < baseFunc->defaultArgs.GetLength(); n++) |
| 3210 | if (baseFunc->defaultArgs[n]) |
| 3211 | newFunc->defaultArgs.PushLast(asNEW(asCString)(*baseFunc->defaultArgs[n])); |
| 3212 | else |
| 3213 | newFunc->defaultArgs.PushLast(0); |
| 3214 | newFunc->parameterNames = baseFunc->parameterNames; |
| 3215 | newFunc->inOutFlags = baseFunc->inOutFlags; |
| 3216 | newFunc->traits = baseFunc->traits; |
| 3217 | newFunc->SetReadOnly(baseFunc->IsReadOnly()); |
| 3218 | newFunc->objectType = baseFunc->objectType; |
| 3219 | if( newFunc->objectType ) newFunc->objectType->AddRefInternal(); |
| 3220 | newFunc->sysFuncIntf = asNEW(asSSystemFunctionInterface)(*baseFunc->sysFuncIntf); |
| 3221 | newFunc->funcType = asFUNC_SYSTEM; |
| 3222 | newFunc->nameSpace = baseFunc->nameSpace; |
| 3223 | |
| 3224 | // TODO: Need to know the module if it is a script that instantiates the template function |
| 3225 | newFunc->returnType = DetermineTypeForTemplate(baseFunc->returnType, baseFunc->templateSubTypes, types, 0, 0, 0); |
| 3226 | newFunc->parameterTypes.SetLength(baseFunc->parameterTypes.GetLength()); |
| 3227 | for (asUINT p = 0; p < baseFunc->parameterTypes.GetLength(); p++) |
| 3228 | newFunc->parameterTypes[p] = DetermineTypeForTemplate(baseFunc->parameterTypes[p], baseFunc->templateSubTypes, types, 0, 0, 0); |
| 3229 | |
| 3230 | newFunc->templateSubTypes = types; |
| 3231 | for (asUINT t = 0; t < newFunc->templateSubTypes.GetLength(); t++) |
| 3232 | if (newFunc->templateSubTypes[t].GetTypeInfo()) |
| 3233 | newFunc->templateSubTypes[t].GetTypeInfo()->AddRefInternal(); |
| 3234 | |
| 3235 | newFunc->id = GetNextScriptFunctionId(); |
| 3236 | AddScriptFunction(newFunc); |
| 3237 | |
| 3238 | // Keep track of template function instances |
| 3239 | generatedTemplateFunctionInstances.PushLast(newFunc); // This holds a reference (constructor already set it to 1) |
| 3240 | |
| 3241 | // Adjust the clean up instructions |
| 3242 | if (newFunc->sysFuncIntf->callConv == ICC_GENERIC_FUNC || |
| 3243 | newFunc->sysFuncIntf->callConv == ICC_GENERIC_METHOD) |
| 3244 | PrepareSystemFunctionGeneric(newFunc, newFunc->sysFuncIntf, this); |
no test coverage detected