Update Angelscript from 2.32.0 to 2.35.1

Didn't require any changes except dos2unix.
This commit is contained in:
Bryan Quigley
2021-11-04 13:43:10 -07:00
parent 0d8b01b08b
commit 73c94f571d
37 changed files with 5585 additions and 2550 deletions

View File

@@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2017 Andreas Jonsson
Copyright (c) 2003-2021 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
@@ -218,6 +218,9 @@ AS_API const char * asGetLibraryOptions()
#endif
#ifdef AS_SPARC
"AS_SPARC "
#endif
#ifdef AS_ARM64
"AS_ARM64 "
#endif
;
@@ -291,18 +294,24 @@ int asCScriptEngine::SetEngineProperty(asEEngineProp property, asPWORD value)
{
// Restore default: no limit and initially size 4KB
ep.maximumContextStackSize = 0;
initialContextStackSize = 1024;
}
else
{
// The size is given in bytes, but we only store dwords
ep.maximumContextStackSize = (asUINT)value/4;
if( initialContextStackSize > ep.maximumContextStackSize )
{
initialContextStackSize = ep.maximumContextStackSize;
if( initialContextStackSize == 0 )
initialContextStackSize = 1;
}
}
break;
case asEP_INIT_STACK_SIZE:
if (value < 4)
{
// At least one dword
ep.initContextStackSize = 1;
}
else
{
// The size is given in bytes, but we only store dwords
ep.initContextStackSize = (asUINT)value / 4;
}
break;
@@ -349,7 +358,7 @@ int asCScriptEngine::SetEngineProperty(asEEngineProp property, asPWORD value)
break;
case asEP_PROPERTY_ACCESSOR_MODE:
if( value <= 2 )
if( value <= 3 )
ep.propertyAccessorMode = (int)value;
else
return asINVALID_ARG;
@@ -419,6 +428,21 @@ int asCScriptEngine::SetEngineProperty(asEEngineProp property, asPWORD value)
ep.maxNestedCalls = (asUINT)value;
break;
case asEP_GENERIC_CALL_MODE:
if (value > 1)
ep.genericCallMode = 1;
else
ep.genericCallMode = (asUINT)value;
break;
case asEP_INIT_CALL_STACK_SIZE:
ep.initCallStackSize = (asUINT)value;
break;
case asEP_MAX_CALL_STACK_SIZE:
ep.maxCallStackSize = (asUINT)value;
break;
default:
return asINVALID_ARG;
}
@@ -441,7 +465,10 @@ asPWORD asCScriptEngine::GetEngineProperty(asEEngineProp property) const
return ep.copyScriptSections;
case asEP_MAX_STACK_SIZE:
return ep.maximumContextStackSize*4;
return ep.maximumContextStackSize * 4;
case asEP_INIT_STACK_SIZE:
return ep.initContextStackSize * 4;
case asEP_USE_CHARACTER_LITERALS:
return ep.useCharacterLiterals;
@@ -512,6 +539,15 @@ asPWORD asCScriptEngine::GetEngineProperty(asEEngineProp property) const
case asEP_MAX_NESTED_CALLS:
return ep.maxNestedCalls;
case asEP_GENERIC_CALL_MODE:
return ep.genericCallMode;
case asEP_INIT_CALL_STACK_SIZE:
return ep.initCallStackSize;
case asEP_MAX_CALL_STACK_SIZE:
return ep.maxCallStackSize;
default:
return 0;
}
@@ -551,6 +587,7 @@ asCScriptEngine::asCScriptEngine()
ep.optimizeByteCode = true;
ep.copyScriptSections = true;
ep.maximumContextStackSize = 0; // no limit
ep.initContextStackSize = 1024; // 4KB default init stack size
ep.useCharacterLiterals = false;
ep.allowMultilineStrings = false;
ep.allowImplicitHandleTypes = false;
@@ -562,7 +599,7 @@ asCScriptEngine::asCScriptEngine()
ep.scanner = 1; // utf8. 0 = ascii
ep.includeJitInstructions = false;
ep.stringEncoding = 0; // utf8. 1 = utf16
ep.propertyAccessorMode = 2; // 0 = disable, 1 = app registered only, 2 = app and script created
ep.propertyAccessorMode = 3; // 0 = disable, 1 = app registered only, 2 = app and script created, 3 = flag with 'property'
ep.expandDefaultArrayToTemplate = false;
ep.autoGarbageCollect = true;
ep.disallowGlobalVars = false;
@@ -577,6 +614,9 @@ asCScriptEngine::asCScriptEngine()
ep.allowUnicodeIdentifiers = false;
ep.heredocTrimMode = 1; // 0 = never trim, 1 = don't trim on single line, 2 = trim initial and final empty line
ep.maxNestedCalls = 100;
ep.genericCallMode = 1; // 0 = old (pre 2.33.0) behavior where generic ignored auto handles, 1 = treat handles like in native call
ep.initCallStackSize = 10; // 10 levels of calls
ep.maxCallStackSize = 0; // 0 = no limit
}
gc.engine = this;
@@ -590,10 +630,6 @@ asCScriptEngine::asCScriptEngine()
deferValidationOfTemplateTypes = false;
lastModule = 0;
initialContextStackSize = 1024; // 4 KB (1024 * sizeof(asDWORD)
typeIdSeqNbr = 0;
currentGroup = &defaultGroup;
defaultAccessMask = 0xFFFFFFFF; // All bits set so that built-in functions/types will be available to all modules
@@ -638,6 +674,10 @@ asCScriptEngine::asCScriptEngine()
RegisterScriptObject(this);
RegisterScriptFunction(this);
#ifndef AS_NO_EXCEPTIONS
translateExceptionCallback = false;
#endif
}
void asCScriptEngine::DeleteDiscardedModules()
@@ -701,10 +741,10 @@ asCScriptEngine::~asCScriptEngine()
}
// Delete the functions for generated template types that may references object types
for( asUINT n = 0; n < templateInstanceTypes.GetLength(); n++ )
for( asUINT n = 0; n < generatedTemplateTypes.GetLength(); n++ )
{
asCObjectType *templateType = templateInstanceTypes[n];
if( templateInstanceTypes[n] )
asCObjectType *templateType = generatedTemplateTypes[n];
if( templateType )
templateType->DestroyInternal();
}
for( asUINT n = 0; n < listPatternTypes.GetLength(); n++ )
@@ -882,13 +922,15 @@ asCModule *asCScriptEngine::FindNewOwnerForSharedType(asCTypeInfo *in_type, asCM
asCModule *mod = scriptModules[n];
if( mod == in_type->module ) continue;
if( in_type->flags & asOBJ_ENUM )
foundIdx = mod->enumTypes.IndexOf(CastToEnumType(in_type));
foundIdx = mod->m_enumTypes.IndexOf(CastToEnumType(in_type));
else if (in_type->flags & asOBJ_TYPEDEF)
foundIdx = mod->typeDefs.IndexOf(CastToTypedefType(in_type));
foundIdx = mod->m_typeDefs.IndexOf(CastToTypedefType(in_type));
else if (in_type->flags & asOBJ_FUNCDEF)
foundIdx = mod->funcDefs.IndexOf(CastToFuncdefType(in_type));
foundIdx = mod->m_funcDefs.IndexOf(CastToFuncdefType(in_type));
else if (in_type->flags & asOBJ_TEMPLATE)
foundIdx = mod->m_templateInstances.IndexOf(CastToObjectType(in_type));
else
foundIdx = mod->classTypes.IndexOf(CastToObjectType(in_type));
foundIdx = mod->m_classTypes.IndexOf(CastToObjectType(in_type));
if( foundIdx >= 0 )
{
@@ -909,13 +951,34 @@ asCModule *asCScriptEngine::FindNewOwnerForSharedFunc(asCScriptFunction *in_func
if( in_func->module != in_mod)
return in_func->module;
// Check if this is a class method or class factory for a type that has already been moved to a different module
if ((in_func->objectType && in_func->objectType->module && in_func->objectType->module != in_func->module) ||
(in_func->IsFactory() && in_func->returnType.GetTypeInfo()->module && in_func->returnType.GetTypeInfo()->module != in_func->module))
{
// The object type for the method has already been transferred to
// another module, so transfer the method to the same module
if (in_func->objectType)
in_func->module = in_func->objectType->module;
else
in_func->module = in_func->returnType.GetTypeInfo()->module;
// Make sure the function is listed in the module
// The compiler may not have done this earlier, since the object
// type is shared and originally compiled from another module
if (in_func->module->m_scriptFunctions.IndexOf(in_func) < 0)
{
in_func->module->m_scriptFunctions.PushLast(in_func);
in_func->AddRefInternal();
}
}
for( asUINT n = 0; n < scriptModules.GetLength(); n++ )
{
// TODO: optimize: If the modules already stored the shared types separately, this would be quicker
int foundIdx = -1;
asCModule *mod = scriptModules[n];
if( mod == in_func->module ) continue;
foundIdx = mod->scriptFunctions.IndexOf(in_func);
foundIdx = mod->m_scriptFunctions.IndexOf(in_func);
if( foundIdx >= 0 )
{
@@ -1311,7 +1374,9 @@ int asCScriptEngine::GetFactoryIdByDecl(const asCObjectType *ot, const char *dec
for( asUINT n = 0; n < ot->beh.factories.GetLength(); n++ )
{
asCScriptFunction *f = scriptFunctions[ot->beh.factories[n]];
if( f->IsSignatureEqual(&func) )
// We don't really care if the name of the function is correct
if( f->IsSignatureExceptNameEqual(&func) )
{
id = ot->beh.factories[n];
break;
@@ -1456,7 +1521,9 @@ int asCScriptEngine::RegisterObjectProperty(const char *obj, const char *declara
prop->isCompositeIndirect = isCompositeIndirect;
prop->accessMask = defaultAccessMask;
CastToObjectType(dt.GetTypeInfo())->properties.PushLast(prop);
asCObjectType *ot = CastToObjectType(dt.GetTypeInfo());
asUINT idx = ot->properties.GetLength();
ot->properties.PushLast(prop);
// Add references to types so they are not released too early
if( type.GetTypeInfo() )
@@ -1470,7 +1537,8 @@ int asCScriptEngine::RegisterObjectProperty(const char *obj, const char *declara
currentGroup->AddReferencesForType(this, type.GetTypeInfo());
return asSUCCESS;
// Return the index of the property to signal success
return idx;
}
// interface
@@ -1502,7 +1570,7 @@ int asCScriptEngine::RegisterInterface(const char *name)
if( token != ttIdentifier || strlen(name) != tokenLen )
return ConfigError(asINVALID_NAME, "RegisterInterface", name, 0);
r = bld.CheckNameConflict(name, 0, 0, defaultNamespace);
r = bld.CheckNameConflict(name, 0, 0, defaultNamespace, true, false);
if( r < 0 )
return ConfigError(asNAME_TAKEN, "RegisterInterface", name, 0);
@@ -1564,7 +1632,7 @@ int asCScriptEngine::RegisterInterfaceMethod(const char *intf, const char *decla
}
// Check name conflicts
r = bld.CheckNameConflictMember(dt.GetTypeInfo(), func->name.AddressOf(), 0, 0, false);
r = bld.CheckNameConflictMember(dt.GetTypeInfo(), func->name.AddressOf(), 0, 0, false, false);
if( r < 0 )
{
func->funcType = asFUNC_DUMMY;
@@ -1620,7 +1688,7 @@ int asCScriptEngine::RegisterObjectType(const char *name, int byteSize, asDWORD
else if( flags & asOBJ_VALUE )
{
// Cannot use reference flags
if( flags & (asOBJ_REF | asOBJ_GC | asOBJ_NOHANDLE | asOBJ_SCOPED | asOBJ_NOCOUNT | asOBJ_IMPLICIT_HANDLE) )
if( flags & (asOBJ_REF | asOBJ_NOHANDLE | asOBJ_SCOPED | asOBJ_NOCOUNT | asOBJ_IMPLICIT_HANDLE) )
return ConfigError(asINVALID_ARG, "RegisterObjectType", name, 0);
// Flags are exclusive
@@ -1763,16 +1831,6 @@ int asCScriptEngine::RegisterObjectType(const char *name, int byteSize, asDWORD
// This is not an irrepairable error, as it may just be that the same type is registered twice
return asALREADY_REGISTERED;
// TODO: clean up: Is it really necessary to check here?
for( asUINT n = 0; n < templateInstanceTypes.GetLength(); n++ )
{
if( templateInstanceTypes[n] &&
templateInstanceTypes[n]->name == typeName &&
templateInstanceTypes[n]->nameSpace == defaultNamespace )
// This is not an irrepairable error, as it may just be that the same type is registered twice
return asALREADY_REGISTERED;
}
// Keep the most recent template generated instance type, so we know what it was before parsing the datatype
asCObjectType *mostRecentTemplateInstanceType = 0;
asUINT originalSizeOfGeneratedTemplateTypes = (asUINT)generatedTemplateTypes.GetLength();
@@ -1795,7 +1853,7 @@ int asCScriptEngine::RegisterObjectType(const char *name, int byteSize, asDWORD
if( token != ttIdentifier || typeName.GetLength() != tokenLen )
return ConfigError(asINVALID_NAME, "RegisterObjectType", name, 0);
r = bld.CheckNameConflict(name, 0, 0, defaultNamespace);
r = bld.CheckNameConflict(name, 0, 0, defaultNamespace, true, false);
if( r < 0 )
return ConfigError(asNAME_TAKEN, "RegisterObjectType", name, 0);
@@ -2082,6 +2140,8 @@ int asCScriptEngine::RegisterBehaviourToObjectType(asCObjectType *objectType, as
}
else if( behaviour == asBEHAVE_LIST_CONSTRUCT )
{
func.name = "$list";
// Verify that the return type is void
if( func.returnType != asCDataType::CreatePrimitive(ttVoid, false) )
{
@@ -2102,7 +2162,9 @@ int asCScriptEngine::RegisterBehaviourToObjectType(asCObjectType *objectType, as
}
// Verify the parameters
if( func.parameterTypes.GetLength() != 1 || !func.parameterTypes[0].IsReference() )
// The templates take a hidden parameter with the object type
if( (!(objectType->flags & asOBJ_TEMPLATE) && (func.parameterTypes.GetLength() != 1 || !func.parameterTypes[0].IsReference())) ||
((objectType->flags & asOBJ_TEMPLATE) && (func.parameterTypes.GetLength() != 2 || !func.parameterTypes[0].IsReference() || !func.parameterTypes[1].IsReference())) )
{
if( listPattern )
listPattern->Destroy(this);
@@ -2137,6 +2199,9 @@ int asCScriptEngine::RegisterBehaviourToObjectType(asCObjectType *objectType, as
}
else if( behaviour == asBEHAVE_FACTORY || behaviour == asBEHAVE_LIST_FACTORY )
{
if( behaviour == asBEHAVE_LIST_FACTORY )
func.name = "$list";
// Must be a ref type and must not have asOBJ_NOHANDLE
if( !(objectType->flags & asOBJ_REF) || (objectType->flags & asOBJ_NOHANDLE) )
{
@@ -2433,8 +2498,8 @@ int asCScriptEngine::SetTemplateRestrictions(asCObjectType *templateType, asCScr
{
if (func->parameterTypes[n].GetTypeInfo() == templateType->templateSubTypes[subTypeIdx].GetTypeInfo())
{
// TODO: If unsafe references are allowed, then inout references allow value types
if (func->parameterTypes[n].IsObjectHandle() || (func->parameterTypes[n].IsReference() && func->inOutFlags[n] == asTM_INOUTREF))
if (func->parameterTypes[n].IsObjectHandle() ||
(!ep.allowUnsafeReferences && func->parameterTypes[n].IsReference() && func->inOutFlags[n] == asTM_INOUTREF))
templateType->acceptValueSubType = false;
else if (!func->parameterTypes[n].IsReference())
templateType->acceptRefSubType = false;
@@ -2492,6 +2557,7 @@ int asCScriptEngine::AddBehaviourFunction(asCScriptFunction &func, asSSystemFunc
f->parameterTypes = func.parameterTypes;
f->parameterNames = func.parameterNames;
f->inOutFlags = func.inOutFlags;
f->traits = func.traits;
for( n = 0; n < func.defaultArgs.GetLength(); n++ )
if( func.defaultArgs[n] )
f->defaultArgs.PushLast(asNEW(asCString)(*func.defaultArgs[n]));
@@ -2535,13 +2601,14 @@ int asCScriptEngine::RegisterGlobalProperty(const char *declaration, void *point
prop->SetRegisteredAddress(pointer);
varAddressMap.Insert(prop->GetAddressOfValue(), prop);
registeredGlobalProps.Put(prop);
asUINT idx = registeredGlobalProps.Put(prop);
prop->AddRef();
currentGroup->globalProps.PushLast(prop);
currentGroup->AddReferencesForType(this, type.GetTypeInfo());
return asSUCCESS;
// Return the index of the property to signal success
return int(idx);
}
// internal
@@ -2620,10 +2687,13 @@ int asCScriptEngine::GetGlobalPropertyByIndex(asUINT index, const char **name, c
}
// interface
int asCScriptEngine::GetGlobalPropertyIndexByName(const char *name) const
int asCScriptEngine::GetGlobalPropertyIndexByName(const char *in_name) const
{
asSNameSpace *ns = defaultNamespace;
asCString name;
asSNameSpace *ns = 0;
if( DetermineNameAndNamespace(in_name, defaultNamespace, name, ns) < 0 )
return asINVALID_ARG;
// Find the global var id
while( ns )
{
@@ -2763,7 +2833,7 @@ int asCScriptEngine::RegisterMethodToObjectType(asCObjectType *objectType, const
}
// Check name conflicts
r = bld.CheckNameConflictMember(objectType, func->name.AddressOf(), 0, 0, false);
r = bld.CheckNameConflictMember(objectType, func->name.AddressOf(), 0, 0, false, false);
if( r < 0 )
{
func->funcType = asFUNC_DUMMY;
@@ -2771,6 +2841,18 @@ int asCScriptEngine::RegisterMethodToObjectType(asCObjectType *objectType, const
return ConfigError(asNAME_TAKEN, "RegisterObjectMethod", objectType->name.AddressOf(), declaration);
}
// 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, "RegisterObjectMethod", objectType->name.AddressOf(), declaration);
else
return ConfigError(asINVALID_DECLARATION, "RegisterObjectMethod", objectType->name.AddressOf(), declaration);
}
// Check against duplicate methods
if( func->name == "opConv" || func->name == "opImplConv" || func->name == "opCast" || func->name == "opImplCast" )
{
@@ -2877,7 +2959,7 @@ int asCScriptEngine::RegisterGlobalFunction(const char *declaration, const asSFu
func->nameSpace = defaultNamespace;
// Check name conflicts
r = bld.CheckNameConflict(func->name.AddressOf(), 0, 0, defaultNamespace);
r = bld.CheckNameConflict(func->name.AddressOf(), 0, 0, defaultNamespace, false, false);
if( r < 0 )
{
// Set as dummy function before deleting
@@ -2885,6 +2967,18 @@ int asCScriptEngine::RegisterGlobalFunction(const char *declaration, const asSFu
asDELETE(func,asCScriptFunction);
return ConfigError(asNAME_TAKEN, "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, "RegisterGlobalFunction", declaration, 0);
else
return ConfigError(asINVALID_DECLARATION, "RegisterGlobalFunction", declaration, 0);
}
// Make sure the function is not identical to a previously registered function
asUINT n;
@@ -3035,20 +3129,31 @@ void asCScriptEngine::PrepareEngine()
// Verify that GC types have all behaviours
if( type->flags & asOBJ_GC )
{
if( type->beh.addref == 0 ||
type->beh.release == 0 ||
type->beh.gcGetRefCount == 0 ||
type->beh.gcSetFlag == 0 ||
type->beh.gcGetFlag == 0 ||
type->beh.gcEnumReferences == 0 ||
type->beh.gcReleaseAllReferences == 0 )
if (type->flags & asOBJ_REF)
{
infoMsg = TXT_GC_REQUIRE_ADD_REL_GC_BEHAVIOUR;
missingBehaviour = true;
if (type->beh.addref == 0 ||
type->beh.release == 0 ||
type->beh.gcGetRefCount == 0 ||
type->beh.gcSetFlag == 0 ||
type->beh.gcGetFlag == 0 ||
type->beh.gcEnumReferences == 0 ||
type->beh.gcReleaseAllReferences == 0)
{
infoMsg = TXT_GC_REQUIRE_ADD_REL_GC_BEHAVIOUR;
missingBehaviour = true;
}
}
else
{
if (type->beh.gcEnumReferences == 0)
{
infoMsg = TXT_VALUE_GC_REQUIRE_GC_BEHAVIOUR;
missingBehaviour = true;
}
}
}
// Verify that scoped ref types have the release behaviour
else if( type->flags & asOBJ_SCOPED )
if( type->flags & asOBJ_SCOPED )
{
if( type->beh.release == 0 )
{
@@ -3057,9 +3162,10 @@ void asCScriptEngine::PrepareEngine()
}
}
// Verify that ref types have add ref and release behaviours
else if( (type->flags & asOBJ_REF) &&
!(type->flags & asOBJ_NOHANDLE) &&
!(type->flags & asOBJ_NOCOUNT) )
if( (type->flags & asOBJ_REF) &&
!(type->flags & asOBJ_SCOPED) &&
!(type->flags & asOBJ_NOHANDLE) &&
!(type->flags & asOBJ_NOCOUNT) )
{
if( type->beh.addref == 0 ||
type->beh.release == 0 )
@@ -3069,8 +3175,8 @@ void asCScriptEngine::PrepareEngine()
}
}
// Verify that non-pod value types have the constructor and destructor registered
else if( (type->flags & asOBJ_VALUE) &&
!(type->flags & asOBJ_POD) )
if( (type->flags & asOBJ_VALUE) &&
!(type->flags & asOBJ_POD) )
{
if( type->beh.constructors.GetLength() == 0 ||
type->beh.destruct == 0 )
@@ -3103,12 +3209,12 @@ int asCScriptEngine::ConfigError(int err, const char *funcName, const char *arg1
if( arg1 )
{
if( arg2 )
str.Format(TXT_FAILED_IN_FUNC_s_WITH_s_AND_s_d, funcName, arg1, arg2, err);
str.Format(TXT_FAILED_IN_FUNC_s_WITH_s_AND_s_s_d, funcName, arg1, arg2, errorNames[-err], err);
else
str.Format(TXT_FAILED_IN_FUNC_s_WITH_s_d, funcName, arg1, err);
str.Format(TXT_FAILED_IN_FUNC_s_WITH_s_s_d, funcName, arg1, errorNames[-err], err);
}
else
str.Format(TXT_FAILED_IN_FUNC_s_d, funcName, err);
str.Format(TXT_FAILED_IN_FUNC_s_s_d, funcName, errorNames[-err], err);
WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
}
@@ -3188,13 +3294,13 @@ asCModule *asCScriptEngine::GetModule(const char *name, bool create)
asCModule *retModule = 0;
ACQUIRESHARED(engineRWLock);
if( lastModule && lastModule->name == name )
if( lastModule && lastModule->m_name == name )
retModule = lastModule;
else
{
// TODO: optimize: Improve linear search
for( asUINT n = 0; n < scriptModules.GetLength(); ++n )
if( scriptModules[n] && scriptModules[n]->name == name )
if( scriptModules[n] && scriptModules[n]->m_name == name )
{
retModule = scriptModules[n];
break;
@@ -3296,6 +3402,7 @@ asCObjectType *asCScriptEngine::GetTemplateInstanceType(asCObjectType *templateT
asCObjectType *type = templateInstanceTypes[n];
if( type &&
type->name == templateType->name &&
type->nameSpace == templateType->nameSpace &&
type->templateSubTypes == subTypes )
{
// If the template instance is generated, then the module should hold a reference
@@ -3309,9 +3416,9 @@ asCObjectType *asCScriptEngine::GetTemplateInstanceType(asCObjectType *templateT
// It may be without ownership if it was previously created from application with for example GetTypeInfoByDecl
type->module = requestingModule;
}
if( !requestingModule->templateInstances.Exists(type) )
if( !requestingModule->m_templateInstances.Exists(type) )
{
requestingModule->templateInstances.PushLast(type);
requestingModule->m_templateInstances.PushLast(type);
type->AddRefInternal();
}
}
@@ -3351,7 +3458,7 @@ asCObjectType *asCScriptEngine::GetTemplateInstanceType(asCObjectType *templateT
{
// Set the ownership of this template type
ot->module = requestingModule;
requestingModule->templateInstances.PushLast(ot);
requestingModule->m_templateInstances.PushLast(ot);
ot->AddRefInternal();
}
else
@@ -3367,7 +3474,7 @@ asCObjectType *asCScriptEngine::GetTemplateInstanceType(asCObjectType *templateT
ot->module = subTypes[n].GetTypeInfo()->module;
if( ot->module )
{
ot->module->templateInstances.PushLast(ot);
ot->module->m_templateInstances.PushLast(ot);
ot->AddRefInternal();
break;
}
@@ -3391,7 +3498,7 @@ asCObjectType *asCScriptEngine::GetTemplateInstanceType(asCObjectType *templateT
ot->templateSubTypes.SetLength(0);
if( ot->module )
{
ot->module->templateInstances.RemoveValue(ot);
ot->module->m_templateInstances.RemoveValue(ot);
ot->ReleaseInternal();
}
ot->ReleaseInternal();
@@ -3613,6 +3720,11 @@ asCDataType asCScriptEngine::DetermineTypeForTemplate(const asCDataType &orig, a
dt.MakeReference(orig.IsReference());
dt.MakeReadOnly(ot->templateSubTypes[n].IsReadOnly() || orig.IsReadOnly());
// If the target is a @& then don't make the handle const,
// as it is not possible to declare functions with @const &
if (orig.IsReference() && dt.IsObjectHandle())
dt.MakeReadOnly(false);
}
break;
}
@@ -3665,7 +3777,8 @@ asCDataType asCScriptEngine::DetermineTypeForTemplate(const asCDataType &orig, a
// Always find the original template type when creating a new template instance otherwise the
// generation will fail since it will attempt to create factory stubs when they already exists, etc
for( asUINT n = 0; n < registeredTemplateTypes.GetLength(); n++ )
if( registeredTemplateTypes[n]->name == origType->name )
if( registeredTemplateTypes[n]->name == origType->name &&
registeredTemplateTypes[n]->nameSpace == origType->nameSpace )
{
origType = registeredTemplateTypes[n];
break;
@@ -3727,6 +3840,7 @@ asCScriptFunction *asCScriptEngine::GenerateTemplateFactoryStub(asCObjectType *t
func->id = GetNextScriptFunctionId();
AddScriptFunction(func);
func->traits = factory->traits;
func->SetShared(true);
if( templateType->flags & asOBJ_REF )
{
@@ -3846,7 +3960,13 @@ bool asCScriptEngine::RequireTypeReplacement(asCDataType &type, asCObjectType *t
bool asCScriptEngine::GenerateNewTemplateFunction(asCObjectType *templateType, asCObjectType *ot, asCScriptFunction *func, asCScriptFunction **newFunc)
{
// Due to the objectType it is always required to generate a new function,
// even if none of the function arguments needs to be changed.
/*
// TODO: Can we store the new function in some other optimized way to avoid
// duplicating all information just because of the different objectType member?
bool needNewFunc = false;
if( RequireTypeReplacement(func->returnType, templateType) )
needNewFunc = true;
else
@@ -3863,6 +3983,7 @@ bool asCScriptEngine::GenerateNewTemplateFunction(asCObjectType *templateType, a
if( !needNewFunc )
return false;
*/
asCScriptFunction *func2 = asNEW(asCScriptFunction)(this, 0, func->funcType);
if( func2 == 0 )
@@ -3891,6 +4012,7 @@ bool asCScriptEngine::GenerateNewTemplateFunction(asCObjectType *templateType, a
func2->parameterNames = func->parameterNames;
func2->inOutFlags = func->inOutFlags;
func2->traits = func->traits;
func2->SetReadOnly(func->IsReadOnly());
func2->objectType = ot;
func2->objectType->AddRefInternal();
@@ -4606,6 +4728,32 @@ void asCScriptEngine::GCEnumCallback(void *reference)
gc.GCEnumCallback(reference);
}
// interface
void asCScriptEngine::ForwardGCEnumReferences(void *ref, asITypeInfo *type)
{
asCTypeInfo *t = reinterpret_cast<asCTypeInfo*>(type);
if ((t->flags & asOBJ_VALUE) && (t->flags & asOBJ_GC))
{
CallObjectMethod(ref, this, CastToObjectType(t)->beh.gcEnumReferences);
}
}
// interface
void asCScriptEngine::ForwardGCReleaseReferences(void *ref, asITypeInfo *type)
{
asCTypeInfo *t = reinterpret_cast<asCTypeInfo*>(type);
if ((t->flags & asOBJ_VALUE) && (t->flags & asOBJ_GC))
{
CallObjectMethod(ref, this, CastToObjectType(t)->beh.gcReleaseAllReferences);
}
}
// interface
void asCScriptEngine::SetCircularRefDetectedCallback(asCIRCULARREFFUNC_t callback, void *param)
{
gc.circularRefDetectCallbackFunc = callback;
gc.circularRefDetectCallbackParam = param;
}
int asCScriptEngine::GetTypeIdFromDataType(const asCDataType &dtIn) const
{
@@ -4820,7 +4968,8 @@ int asCScriptEngine::RefCastObject(void *obj, asITypeInfo *fromType, asITypeInfo
// Look for ref cast behaviours
asCScriptFunction *universalCastFunc = 0;
asCObjectType *from = reinterpret_cast<asCObjectType*>(fromType);
asCObjectType *from = CastToObjectType(reinterpret_cast< asCTypeInfo*>(fromType));
if( from == 0 ) return asINVALID_ARG;
for( asUINT n = 0; n < from->methods.GetLength(); n++ )
{
asCScriptFunction *func = scriptFunctions[from->methods[n]];
@@ -4837,11 +4986,10 @@ int asCScriptEngine::RefCastObject(void *obj, asITypeInfo *fromType, asITypeInfo
AddRefScriptObject(*newPtr, toType);
return asSUCCESS;
}
else
else if( func->returnType.GetTokenType() == ttVoid &&
func->parameterTypes.GetLength() == 1 &&
func->parameterTypes[0].GetTokenType() == ttQuestion )
{
asASSERT( func->returnType.GetTokenType() == ttVoid &&
func->parameterTypes.GetLength() == 1 &&
func->parameterTypes[0].GetTokenType() == ttQuestion );
universalCastFunc = func;
}
}
@@ -4905,15 +5053,18 @@ void *asCScriptEngine::CreateScriptObject(const asITypeInfo *type)
{
if( type == 0 ) return 0;
asCObjectType *objType = const_cast<asCObjectType*>(reinterpret_cast<const asCObjectType *>(type));
asCObjectType *objType = CastToObjectType(const_cast<asCTypeInfo*>(reinterpret_cast<const asCTypeInfo*>(type)));
if (objType == 0) return 0;
void *ptr = 0;
// Check that there is a default factory for ref types
if( objType->beh.factory == 0 && (objType->flags & asOBJ_REF) )
{
asCString str;
str.Format(TXT_FAILED_IN_FUNC_s_d, "CreateScriptObject", asNO_FUNCTION);
WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
// TODO: How to report the reason the object couldn't be created, without writing to the message callback? optional argument with return code?
// TODO: Warn about the invalid call to message callback. Make it an optional, so the warning can be turned off
// asCString str;
// str.Format(TXT_FAILED_IN_FUNC_s_s_d, "CreateScriptObject", errorNames[-asNO_FUNCTION], asNO_FUNCTION);
// WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
return 0;
}
@@ -4936,9 +5087,9 @@ void *asCScriptEngine::CreateScriptObject(const asITypeInfo *type)
}
catch (...)
{
asIScriptContext *ctx = asGetActiveContext();
asCContext *ctx = reinterpret_cast<asCContext*>(asGetActiveContext());
if (ctx)
ctx->SetException(TXT_EXCEPTION_CAUGHT);
ctx->HandleAppException();
}
#endif
}
@@ -4954,9 +5105,9 @@ void *asCScriptEngine::CreateScriptObject(const asITypeInfo *type)
}
catch(...)
{
asIScriptContext *ctx = asGetActiveContext();
asCContext *ctx = reinterpret_cast<asCContext*>(asGetActiveContext());
if( ctx )
ctx->SetException(TXT_EXCEPTION_CAUGHT);
ctx->HandleAppException();
}
#endif
}
@@ -4965,9 +5116,11 @@ void *asCScriptEngine::CreateScriptObject(const asITypeInfo *type)
// Make sure there is a default constructor or that it is a POD type
if( objType->beh.construct == 0 && !(objType->flags & asOBJ_POD) )
{
asCString str;
str.Format(TXT_FAILED_IN_FUNC_s_d, "CreateScriptObject", asNO_FUNCTION);
WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
// TODO: How to report the reason the object couldn't be created, without writing to the message callback? optional argument with return code?
// TODO: Warn about the invalid call to message callback. Make it an optional, so the warning can be turned off
// asCString str;
// str.Format(TXT_FAILED_IN_FUNC_s_s_d, "CreateScriptObject", errorNames[-asNO_FUNCTION], asNO_FUNCTION);
// WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
return 0;
}
@@ -4992,9 +5145,9 @@ void *asCScriptEngine::CreateScriptObject(const asITypeInfo *type)
}
catch (...)
{
asIScriptContext *ctx = asGetActiveContext();
asCContext *ctx = reinterpret_cast<asCContext*>(asGetActiveContext());
if (ctx)
ctx->SetException(TXT_EXCEPTION_CAUGHT);
ctx->HandleAppException();
// Free the memory
CallFree(ptr);
@@ -5100,7 +5253,9 @@ void *asCScriptEngine::CreateUninitializedScriptObject(const asITypeInfo *type)
if( type == 0 || !(type->GetFlags() & asOBJ_SCRIPT_OBJECT) )
return 0;
asCObjectType *objType = const_cast<asCObjectType*>(reinterpret_cast<const asCObjectType*>(type));
asCObjectType *objType = CastToObjectType(const_cast<asCTypeInfo*>(reinterpret_cast<const asCTypeInfo*>(type)));
if (objType == 0)
return 0;
// Construct the object, but do not call the actual constructor that initializes the members
// The initialization will be done by the application afterwards, e.g. through serialization.
@@ -5117,11 +5272,35 @@ void *asCScriptEngine::CreateScriptObjectCopy(void *origObj, const asITypeInfo *
{
if( origObj == 0 || type == 0 ) return 0;
const asCObjectType* ot = CastToObjectType(const_cast<asCTypeInfo*>(reinterpret_cast<const asCTypeInfo*>(type)));
if (ot == 0) return 0;
void *newObj = 0;
const asCObjectType *ot = reinterpret_cast<const asCObjectType*>(type);
// TODO: runtime optimize: Should call copy factory for ref types too
if( ot->beh.copyconstruct )
if ((ot->flags & asOBJ_SCRIPT_OBJECT) && ot->beh.copyfactory)
{
// Call the script class' default factory with a context
newObj = ScriptObjectCopyFactory(ot, origObj, this);
}
else if (ot->beh.copyfactory)
{
// Call the copy factory which will allocate the memory then copy the original object
#ifdef AS_NO_EXCEPTIONS
newObj = CallGlobalFunctionRetPtr(ot->beh.copyfactory, origObj);
#else
try
{
newObj = CallGlobalFunctionRetPtr(ot->beh.copyfactory, origObj);
}
catch (...)
{
asCContext *ctx = reinterpret_cast<asCContext*>(asGetActiveContext());
if (ctx)
ctx->HandleAppException();
}
#endif
}
else if(ot->beh.copyconstruct )
{
// Manually allocate the memory, then call the copy constructor
newObj = CallAlloc(ot);
@@ -5134,9 +5313,9 @@ void *asCScriptEngine::CreateScriptObjectCopy(void *origObj, const asITypeInfo *
}
catch(...)
{
asIScriptContext *ctx = asGetActiveContext();
asCContext *ctx = reinterpret_cast<asCContext*>(asGetActiveContext());
if( ctx )
ctx->SetException(TXT_EXCEPTION_CAUGHT);
ctx->HandleAppException();
// Free the memory
CallFree(newObj);
@@ -5183,15 +5362,20 @@ void asCScriptEngine::ConstructScriptObjectCopy(void *mem, void *obj, asCObjectT
// interface
int asCScriptEngine::AssignScriptObject(void *dstObj, void *srcObj, const asITypeInfo *type)
{
// TODO: Warn about invalid call in message stream
// TODO: Should a script exception be set in case a context is active?
// TODO: Warn about invalid call in message stream (make it optional)
if( type == 0 || dstObj == 0 || srcObj == 0 ) return asINVALID_ARG;
const asCObjectType *objType = reinterpret_cast<const asCObjectType*>(type);
const asCObjectType *objType = CastToObjectType(const_cast<asCTypeInfo*>(reinterpret_cast<const asCTypeInfo*>(type)));
if (objType == 0) return asINVALID_ARG;
// If value assign for ref types has been disabled, then don't do anything if the type is a ref type
if( ep.disallowValueAssignForRefType && (objType->flags & asOBJ_REF) && !(objType->flags & asOBJ_SCOPED) )
if (ep.disallowValueAssignForRefType && (objType->flags & asOBJ_REF) && !(objType->flags & asOBJ_SCOPED))
{
asIScriptContext *ctx = asGetActiveContext();
if (ctx)
ctx->SetException("Cannot do value assignment");
return asNOT_SUPPORTED;
}
// Must not copy if the opAssign is not available and the object is not a POD object
if( objType->beh.copy )
@@ -5220,7 +5404,7 @@ void asCScriptEngine::AddRefScriptObject(void *obj, const asITypeInfo *type)
// Make sure it is not a null pointer
if( obj == 0 || type == 0 ) return;
const asCTypeInfo *ti = static_cast<const asCTypeInfo*>(type);
const asCTypeInfo *ti = reinterpret_cast<const asCTypeInfo*>(type);
if (ti->flags & asOBJ_FUNCDEF)
{
CallObjectMethod(obj, functionBehaviours.beh.addref);
@@ -5242,7 +5426,7 @@ void asCScriptEngine::ReleaseScriptObject(void *obj, const asITypeInfo *type)
// Make sure it is not a null pointer
if( obj == 0 || type == 0 ) return;
const asCTypeInfo *ti = static_cast<const asCTypeInfo*>(type);
const asCTypeInfo *ti = reinterpret_cast<const asCTypeInfo*>(type);
if (ti->flags & asOBJ_FUNCDEF)
{
CallObjectMethod(obj, functionBehaviours.beh.release);
@@ -5546,7 +5730,7 @@ int asCScriptEngine::RegisterFuncdef(const char *decl)
}
// Check name conflicts
r = bld.CheckNameConflict(func->name.AddressOf(), 0, 0, defaultNamespace);
r = bld.CheckNameConflict(func->name.AddressOf(), 0, 0, defaultNamespace, true, false);
if( r < 0 )
{
asDELETE(func,asCScriptFunction);
@@ -5641,7 +5825,7 @@ asCFuncdefType *asCScriptEngine::FindMatchingFuncdef(asCScriptFunction *func, as
// Add the new funcdef to the module so it will
// be available when saving the bytecode
funcDef->module = module;
module->funcDefs.PushLast(funcDef); // the refCount was already accounted for in the constructor
module->AddFuncDef(funcDef); // the refCount was already accounted for in the constructor
}
// Observe, if the funcdef is created without informing a module a reference will be stored in the
@@ -5653,9 +5837,9 @@ asCFuncdefType *asCScriptEngine::FindMatchingFuncdef(asCScriptFunction *func, as
{
// Unless this is a registered funcDef the returned funcDef must
// be stored as part of the module for saving/loading bytecode
if (!module->funcDefs.Exists(funcDef))
if (!module->m_funcDefs.Exists(funcDef))
{
module->funcDefs.PushLast(funcDef);
module->AddFuncDef(funcDef);
funcDef->AddRefInternal();
}
else
@@ -5717,7 +5901,7 @@ int asCScriptEngine::RegisterTypedef(const char *type, const char *decl)
return ConfigError(asINVALID_NAME, "RegisterTypedef", type, decl);
asCBuilder bld(this, 0);
int r = bld.CheckNameConflict(type, 0, 0, defaultNamespace);
int r = bld.CheckNameConflict(type, 0, 0, defaultNamespace, true, false);
if( r < 0 )
return ConfigError(asNAME_TAKEN, "RegisterTypedef", type, decl);
@@ -5789,7 +5973,7 @@ int asCScriptEngine::RegisterEnum(const char *name)
if( token != ttIdentifier || strlen(name) != tokenLen )
return ConfigError(asINVALID_NAME, "RegisterEnum", name, 0);
r = bld.CheckNameConflict(name, 0, 0, defaultNamespace);
r = bld.CheckNameConflict(name, 0, 0, defaultNamespace, true, false);
if( r < 0 )
return ConfigError(asNAME_TAKEN, "RegisterEnum", name, 0);
@@ -5889,9 +6073,13 @@ asITypeInfo *asCScriptEngine::GetObjectTypeByIndex(asUINT index) const
}
// interface
asITypeInfo *asCScriptEngine::GetTypeInfoByName(const char *name) const
asITypeInfo *asCScriptEngine::GetTypeInfoByName(const char *in_name) const
{
asSNameSpace *ns = defaultNamespace;
asCString name;
asSNameSpace *ns = 0;
if( DetermineNameAndNamespace(in_name, defaultNamespace, name, ns) < 0 )
return 0;
while (ns)
{
// Check the object types
@@ -5934,6 +6122,49 @@ asITypeInfo *asCScriptEngine::GetTypeInfoByName(const char *name) const
return 0;
}
// internal
int asCScriptEngine::DetermineNameAndNamespace(const char *in_name, asSNameSpace *implicitNs, asCString &out_name, asSNameSpace *&out_ns) const
{
if( in_name == 0 )
return asINVALID_ARG;
asCString name = in_name;
asCString scope;
asSNameSpace *ns = implicitNs;
// Check if the given name contains a scope
int pos = name.FindLast("::");
if( pos >= 0 )
{
scope = name.SubString(0, pos);
name = name.SubString(pos+2);
if( pos == 0 )
{
// The scope is '::' so the search must start in the global namespace
ns = nameSpaces[0];
}
else if( scope.SubString(0, 2) == "::" )
{
// The scope starts with '::' so the given scope is fully qualified
ns = FindNameSpace(scope.SubString(2).AddressOf());
}
else
{
// The scope doesn't start with '::' so it is relative to the current namespace
if( implicitNs->name == "" )
ns = FindNameSpace(scope.AddressOf());
else
ns = FindNameSpace((implicitNs->name + "::" + scope).AddressOf());
}
}
out_name = name;
out_ns = ns;
return 0;
}
// interface
asITypeInfo *asCScriptEngine::GetTypeInfoById(int typeId) const
{
@@ -6126,6 +6357,42 @@ void asCScriptEngine::SetScriptObjectUserDataCleanupCallback(asCLEANSCRIPTOBJECT
RELEASEEXCLUSIVE(engineRWLock);
}
// interface
int asCScriptEngine::SetTranslateAppExceptionCallback(asSFuncPtr callback, void *param, int callConv)
{
#ifdef AS_NO_EXCEPTIONS
return asNOT_SUPPORTED;
#else
if (callback.ptr.f.func == 0)
{
// Clear the callback
translateExceptionCallback = false;
return asSUCCESS;
}
// Detect the new callback
translateExceptionCallback = true;
translateExceptionCallbackObj = param;
bool isObj = false;
if ((unsigned)callConv == asCALL_GENERIC || (unsigned)callConv == asCALL_THISCALL_OBJFIRST || (unsigned)callConv == asCALL_THISCALL_OBJLAST)
return asNOT_SUPPORTED;
if ((unsigned)callConv >= asCALL_THISCALL)
{
isObj = true;
if (param == 0)
{
translateExceptionCallback = false;
return asINVALID_ARG;
}
}
int r = DetectCallingConvention(isObj, callback, callConv, 0, &translateExceptionCallbackFunc);
if (r < 0)
translateExceptionCallback = false;
return r;
#endif
}
// internal
asCObjectType *asCScriptEngine::GetListPatternType(int listPatternFuncId)
{