// interface
FLASHMEM int asCScriptEngine::RegisterGlobalFunction(const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv, void *auxiliary)
{
#ifdef AS_MAX_PORTABILITY
if( callConv != asCALL_GENERIC )
return ConfigError(asNOT_SUPPORTED, PSTR("RegisterGlobalFunction"), declaration, 0);
#endif
asSSystemFunctionInterface internal;
int r = DetectCallingConvention(false, funcPointer, callConv, auxiliary, &internal);
if( r < 0 )
return ConfigError(r, PSTR("RegisterGlobalFunction"), declaration, 0);
isPrepared = false; // TODO: Only set this after the validations have been completed, to avoid unnecessary Prepare in case no change was made
// Put the system function in the list of system functions
asSSystemFunctionInterface *newInterface = asNEW(asSSystemFunctionInterface)(internal);
if( newInterface == 0 )
return ConfigError(asOUT_OF_MEMORY, PSTR("RegisterGlobalFunction"), declaration, 0);
asCScriptFunction *func = asNEW(asCScriptFunction)(this, 0, asFUNC_SYSTEM);
if( func == 0 )
{
asDELETE(newInterface, asSSystemFunctionInterface);
return ConfigError(asOUT_OF_MEMORY, PSTR("RegisterGlobalFunction"), declaration, 0);
}
func->sysFuncIntf = newInterface;
asCBuilder bld(this, 0);
r = bld.ParseFunctionDeclaration(0, declaration, func, true, &newInterface->paramAutoHandles, &newInterface->returnAutoHandle, defaultNamespace);
if( r < 0 )
{
// Set as dummy function before deleting
func->funcType = asFUNC_DUMMY;
asDELETE(func,asCScriptFunction);
return ConfigError(asINVALID_DECLARATION, PSTR("RegisterGlobalFunction"), declaration, 0);
}
// TODO: namespace: What if the declaration defined an explicit namespace?
func->nameSpace = defaultNamespace;
// Check name conflicts
r = bld.CheckNameConflict(func->name.AddressOf(), 0, 0, defaultNamespace, false, false, false);
if( r < 0 )
{
// Set as dummy function before deleting
func->funcType = asFUNC_DUMMY;
asDELETE(func,asCScriptFunction);
return ConfigError(asNAME_TAKEN, PSTR("RegisterGlobalFunction"), declaration, 0);
}
// Validate property signature
if( func->IsProperty() && (r = bld.ValidateVirtualProperty(func)) < 0 )
{
// Set as dummy function before deleting
func->funcType = asFUNC_DUMMY;
asDELETE(func,asCScriptFunction);
if( r == -5 )
return ConfigError(asNAME_TAKEN, PSTR("RegisterGlobalFunction"), declaration, 0);
else
return ConfigError(asINVALID_DECLARATION, PSTR("RegisterGlobalFunction"), declaration, 0);
}
// Make sure the function is not identical to a previously registered function
asUINT n;
const asCArray<unsigned int> &idxs = registeredGlobalFuncs.GetIndexes(func->nameSpace, func->name);
for( n = 0; n < idxs.GetLength(); n++ )
{
asCScriptFunction *f = registeredGlobalFuncs.Get(idxs[n]);
if( f->IsSignatureExceptNameAndReturnTypeEqual(func) )
{
func->funcType = asFUNC_DUMMY;
asDELETE(func,asCScriptFunction);
return ConfigError(asALREADY_REGISTERED, PSTR("RegisterGlobalFunction"), declaration, 0);
}
}
func->id = GetNextScriptFunctionId();
AddScriptFunction(func);
currentGroup->scriptFunctions.PushLast(func);
func->accessMask = defaultAccessMask;
registeredGlobalFuncs.Put(func);
// If parameter type from other groups are used, add references
currentGroup->AddReferencesForFunc(this, func);
// Return the function id as success
return func->id;
}