Update to Angelscript 2.35.1
This commit is contained in:
parent
badd37a7d3
commit
6734aa44ec
|
@ -551,12 +551,9 @@ struct Id {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Id<T> id(T /*fn_ptr*/) { return Id<T>(); }
|
Id<T> id(T /*fn_ptr*/) { return Id<T>(); }
|
||||||
|
|
||||||
// On some versions of GNUC it is necessary to use the template keyword as disambiguator,
|
// On GNUC it is necessary to use the template keyword as disambiguator.
|
||||||
// on others the template keyword gives an error, hence the need for the following define.
|
// MSVC seems to accept both with or without the template keyword.
|
||||||
// MSVC on the other hand seems to accept both with or without the template keyword.
|
#if defined(__GNUC__)
|
||||||
#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 4))
|
|
||||||
// GNUC 4.4.3 doesn't need the template keyword, and
|
|
||||||
// hopefully upcoming versions won't need it either
|
|
||||||
#define TMPL template
|
#define TMPL template
|
||||||
#else
|
#else
|
||||||
#define TMPL
|
#define TMPL
|
||||||
|
@ -568,7 +565,7 @@ Id<T> id(T /*fn_ptr*/) { return Id<T>(); }
|
||||||
#define WRAP_OBJ_LAST(name) (::gw::id(name).TMPL ol< name >())
|
#define WRAP_OBJ_LAST(name) (::gw::id(name).TMPL ol< name >())
|
||||||
|
|
||||||
#define WRAP_FN_PR(name, Parameters, ReturnType) asFUNCTION((::gw::Wrapper<ReturnType (*)Parameters>::TMPL f< name >))
|
#define WRAP_FN_PR(name, Parameters, ReturnType) asFUNCTION((::gw::Wrapper<ReturnType (*)Parameters>::TMPL f< name >))
|
||||||
#define WRAP_MFN_PR(ClassType, name, Parameters, ReturnType) asFUNCTION((::gw::Wrapper<ReturnType (ClassType::*)Parameters>::TMPL f< &ClassType::name >))
|
#define WRAP_MFN_PR(ClassType, name, Parameters, ReturnType) asFUNCTION((::gw::Wrapper<ReturnType (ClassType::*)Parameters>::TMPL f< AS_METHOD_AMBIGUITY_CAST(ReturnType (ClassType::*)Parameters)(&ClassType::name) >))
|
||||||
#define WRAP_OBJ_FIRST_PR(name, Parameters, ReturnType) asFUNCTION((::gw::ObjFirst<ReturnType (*)Parameters>::TMPL f< name >))
|
#define WRAP_OBJ_FIRST_PR(name, Parameters, ReturnType) asFUNCTION((::gw::ObjFirst<ReturnType (*)Parameters>::TMPL f< name >))
|
||||||
#define WRAP_OBJ_LAST_PR(name, Parameters, ReturnType) asFUNCTION((::gw::ObjLast<ReturnType (*)Parameters>::TMPL f< name >))
|
#define WRAP_OBJ_LAST_PR(name, Parameters, ReturnType) asFUNCTION((::gw::ObjLast<ReturnType (*)Parameters>::TMPL f< name >))
|
||||||
|
|
||||||
|
|
|
@ -113,12 +113,9 @@ int main()
|
||||||
"template <typename T>\n"
|
"template <typename T>\n"
|
||||||
"Id<T> id(T fn_ptr) { return Id<T>(); }\n"
|
"Id<T> id(T fn_ptr) { return Id<T>(); }\n"
|
||||||
"\n"
|
"\n"
|
||||||
"// On some versions of GNUC it is necessary to use the template keyword as disambiguator,\n"
|
"// On GNUC it is necessary to use the template keyword as disambiguator.\n"
|
||||||
"// on others the template keyword gives an error, hence the need for the following define.\n"
|
"// MSVC seems to accept both with or without the template keyword.\n"
|
||||||
"// MSVC on the other hand seems to accept both with or without the template keyword.\n"
|
"#if defined(__GNUC__)\n"
|
||||||
"#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 4))\n"
|
|
||||||
" // GNUC 4.4.3 doesn't need the template keyword, and\n"
|
|
||||||
" // hopefully upcoming versions won't need it either\n"
|
|
||||||
" #define TMPL template\n"
|
" #define TMPL template\n"
|
||||||
"#else\n"
|
"#else\n"
|
||||||
" #define TMPL\n"
|
" #define TMPL\n"
|
||||||
|
@ -130,7 +127,7 @@ int main()
|
||||||
"#define WRAP_OBJ_LAST(name) (::gw::id(name).TMPL ol< name >())\n"
|
"#define WRAP_OBJ_LAST(name) (::gw::id(name).TMPL ol< name >())\n"
|
||||||
"\n"
|
"\n"
|
||||||
"#define WRAP_FN_PR(name, Parameters, ReturnType) asFUNCTION((::gw::Wrapper<ReturnType (*)Parameters>::TMPL f< name >))\n"
|
"#define WRAP_FN_PR(name, Parameters, ReturnType) asFUNCTION((::gw::Wrapper<ReturnType (*)Parameters>::TMPL f< name >))\n"
|
||||||
"#define WRAP_MFN_PR(ClassType, name, Parameters, ReturnType) asFUNCTION((::gw::Wrapper<ReturnType (ClassType::*)Parameters>::TMPL f< &ClassType::name >))\n"
|
"#define WRAP_MFN_PR(ClassType, name, Parameters, ReturnType) asFUNCTION((::gw::Wrapper<ReturnType (ClassType::*)Parameters>::TMPL f< AS_METHOD_AMBIGUITY_CAST(ReturnType (ClassType::*)Parameters)(&ClassType::name) >))\n"
|
||||||
"#define WRAP_OBJ_FIRST_PR(name, Parameters, ReturnType) asFUNCTION((::gw::ObjFirst<ReturnType (*)Parameters>::TMPL f< name >))\n"
|
"#define WRAP_OBJ_FIRST_PR(name, Parameters, ReturnType) asFUNCTION((::gw::ObjFirst<ReturnType (*)Parameters>::TMPL f< name >))\n"
|
||||||
"#define WRAP_OBJ_LAST_PR(name, Parameters, ReturnType) asFUNCTION((::gw::ObjLast<ReturnType (*)Parameters>::TMPL f< name >))\n"
|
"#define WRAP_OBJ_LAST_PR(name, Parameters, ReturnType) asFUNCTION((::gw::ObjLast<ReturnType (*)Parameters>::TMPL f< name >))\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
|
|
@ -20,6 +20,7 @@ static tm time_point_to_tm(const std::chrono::time_point<std::chrono::system_clo
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
gmtime_s(&local, &t);
|
gmtime_s(&local, &t);
|
||||||
#else
|
#else
|
||||||
|
// TODO: gmtime is not threadsafe
|
||||||
local = *gmtime(&t);
|
local = *gmtime(&t);
|
||||||
#endif
|
#endif
|
||||||
return local;
|
return local;
|
||||||
|
@ -33,23 +34,15 @@ static bool tm_to_time_point(const tm &_tm, std::chrono::time_point<std::chrono:
|
||||||
// Do not rely on timezone, as it is not portable
|
// Do not rely on timezone, as it is not portable
|
||||||
// ref: https://stackoverflow.com/questions/38298261/why-there-is-no-inverse-function-for-gmtime-in-libc
|
// ref: https://stackoverflow.com/questions/38298261/why-there-is-no-inverse-function-for-gmtime-in-libc
|
||||||
// ref: https://stackoverflow.com/questions/8558919/mktime-and-tm-isdst
|
// ref: https://stackoverflow.com/questions/8558919/mktime-and-tm-isdst
|
||||||
localTm.tm_isdst = -1; // Always use current settings, so mktime doesn't modify the time for daylight savings
|
// TODO: mktime is not threadsafe
|
||||||
time_t t = mktime(&localTm);
|
time_t t = mktime(&localTm);
|
||||||
if (t == -1)
|
if (t == -1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Adjust the time_t since epoch with the difference of the local timezone to the universal timezone
|
// Adjust the time_t since epoch with the difference of the local timezone to the universal timezone
|
||||||
|
// TODO: localtime, gmtime, and mktime are not threadsafe
|
||||||
t += (mktime(localtime(&t)) - mktime(gmtime(&t)));
|
t += (mktime(localtime(&t)) - mktime(gmtime(&t)));
|
||||||
|
|
||||||
// Verify if the members were modified, indicating an out-of-range value in input
|
|
||||||
if (localTm.tm_year != _tm.tm_year ||
|
|
||||||
localTm.tm_mon != _tm.tm_mon ||
|
|
||||||
localTm.tm_mday != _tm.tm_mday ||
|
|
||||||
localTm.tm_hour != _tm.tm_hour ||
|
|
||||||
localTm.tm_min != _tm.tm_min ||
|
|
||||||
localTm.tm_sec != _tm.tm_sec)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
tp = system_clock::from_time_t(t);
|
tp = system_clock::from_time_t(t);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -111,7 +104,20 @@ bool CDateTime::setDate(asUINT year, asUINT month, asUINT day)
|
||||||
local.tm_mon = month - 1;
|
local.tm_mon = month - 1;
|
||||||
local.tm_mday = day;
|
local.tm_mday = day;
|
||||||
|
|
||||||
return tm_to_time_point(local, tp);
|
std::chrono::time_point<std::chrono::system_clock> newTp;
|
||||||
|
if (!tm_to_time_point(local, newTp))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check if the date was actually valid
|
||||||
|
tm local2 = time_point_to_tm(newTp);
|
||||||
|
|
||||||
|
if (local.tm_year != local2.tm_year ||
|
||||||
|
local.tm_mon != local2.tm_mon ||
|
||||||
|
local.tm_mday != local2.tm_mday)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
tp = newTp;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDateTime::setTime(asUINT hour, asUINT minute, asUINT second)
|
bool CDateTime::setTime(asUINT hour, asUINT minute, asUINT second)
|
||||||
|
@ -121,7 +127,20 @@ bool CDateTime::setTime(asUINT hour, asUINT minute, asUINT second)
|
||||||
local.tm_min = minute;
|
local.tm_min = minute;
|
||||||
local.tm_sec = second;
|
local.tm_sec = second;
|
||||||
|
|
||||||
return tm_to_time_point(local, tp);
|
std::chrono::time_point<std::chrono::system_clock> newTp;
|
||||||
|
if (!tm_to_time_point(local, newTp))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check if the time was actually valid
|
||||||
|
tm local2 = time_point_to_tm(newTp);
|
||||||
|
|
||||||
|
if (local.tm_hour != local2.tm_hour ||
|
||||||
|
local.tm_min != local2.tm_min ||
|
||||||
|
local.tm_sec != local2.tm_sec)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
tp = newTp;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CDateTime::CDateTime(asUINT year, asUINT month, asUINT day, asUINT hour, asUINT minute, asUINT second)
|
CDateTime::CDateTime(asUINT year, asUINT month, asUINT day, asUINT hour, asUINT minute, asUINT second)
|
||||||
|
|
|
@ -1331,6 +1331,19 @@ void CScriptArray::Copy(void *dst, void *src)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// internal
|
||||||
|
// Swap two elements
|
||||||
|
// Even in arrays of objects the objects are allocated on
|
||||||
|
// the heap and the array stores the pointers to the objects.
|
||||||
|
void CScriptArray::Swap(void* a, void* b)
|
||||||
|
{
|
||||||
|
asBYTE tmp[16];
|
||||||
|
Copy(tmp, a);
|
||||||
|
Copy(a, b);
|
||||||
|
Copy(b, tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// internal
|
// internal
|
||||||
// Return pointer to array item (object handle or primitive value)
|
// Return pointer to array item (object handle or primitive value)
|
||||||
void *CScriptArray::GetArrayItemPointer(int index)
|
void *CScriptArray::GetArrayItemPointer(int index)
|
||||||
|
@ -1574,32 +1587,31 @@ void CScriptArray::Sort(asIScriptFunction *func, asUINT startAt, asUINT count)
|
||||||
if (cmpContext == 0)
|
if (cmpContext == 0)
|
||||||
cmpContext = objType->GetEngine()->RequestContext();
|
cmpContext = objType->GetEngine()->RequestContext();
|
||||||
|
|
||||||
// Insertion sort
|
// TODO: Security issue: If the array is accessed from the callback while the sort is going on the result may be unpredictable
|
||||||
asBYTE tmp[16];
|
// For example, the callback resizes the array in the middle of the sort
|
||||||
for (asUINT i = start + 1; i < end; i++)
|
// Possible solution: set a lock flag on the array, and prohibit modifications while the lock flag is set
|
||||||
|
|
||||||
|
// Bubble sort
|
||||||
|
// TODO: optimize: Use an efficient sort algorithm
|
||||||
|
for (asUINT i = start; i+1 < end; i++)
|
||||||
{
|
{
|
||||||
Copy(tmp, GetArrayItemPointer(i));
|
asUINT best = i;
|
||||||
|
for (asUINT j = i + 1; j < end; j++)
|
||||||
asUINT j = i - 1;
|
|
||||||
|
|
||||||
while (j != 0xFFFFFFFF && j >= start )
|
|
||||||
{
|
{
|
||||||
cmpContext->Prepare(func);
|
cmpContext->Prepare(func);
|
||||||
cmpContext->SetArgAddress(0, GetDataPointer(tmp));
|
cmpContext->SetArgAddress(0, At(j));
|
||||||
cmpContext->SetArgAddress(1, At(j));
|
cmpContext->SetArgAddress(1, At(best));
|
||||||
int r = cmpContext->Execute();
|
int r = cmpContext->Execute();
|
||||||
if (r != asEXECUTION_FINISHED)
|
if (r != asEXECUTION_FINISHED)
|
||||||
break;
|
break;
|
||||||
if (*(bool*)(cmpContext->GetAddressOfReturnValue()))
|
if (*(bool*)(cmpContext->GetAddressOfReturnValue()))
|
||||||
{
|
best = j;
|
||||||
Copy(GetArrayItemPointer(j + 1), GetArrayItemPointer(j));
|
|
||||||
j--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Copy(GetArrayItemPointer(j + 1), tmp);
|
// With Swap we guarantee that the array always sees all references
|
||||||
|
// if the GC calls the EnumReferences in the middle of the sorting
|
||||||
|
if( best != i )
|
||||||
|
Swap(GetArrayItemPointer(i), GetArrayItemPointer(best));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmpContext)
|
if (cmpContext)
|
||||||
|
@ -2170,8 +2182,9 @@ static void RegisterScriptArray_Generic(asIScriptEngine *engine)
|
||||||
r = engine->RegisterObjectMethod("array<T>", "int findByRef(uint startAt, const T&in if_handle_then_const value) const", asFUNCTION(ScriptArrayFindByRef2_Generic), asCALL_GENERIC); assert( r >= 0 );
|
r = engine->RegisterObjectMethod("array<T>", "int findByRef(uint startAt, const T&in if_handle_then_const value) const", asFUNCTION(ScriptArrayFindByRef2_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||||
r = engine->RegisterObjectMethod("array<T>", "bool opEquals(const array<T>&in) const", asFUNCTION(ScriptArrayEquals_Generic), asCALL_GENERIC); assert( r >= 0 );
|
r = engine->RegisterObjectMethod("array<T>", "bool opEquals(const array<T>&in) const", asFUNCTION(ScriptArrayEquals_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||||
r = engine->RegisterObjectMethod("array<T>", "bool isEmpty() const", asFUNCTION(ScriptArrayIsEmpty_Generic), asCALL_GENERIC); assert( r >= 0 );
|
r = engine->RegisterObjectMethod("array<T>", "bool isEmpty() const", asFUNCTION(ScriptArrayIsEmpty_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||||
r = engine->RegisterFuncdef("bool array<T>::less(const T&in a, const T&in b)");
|
r = engine->RegisterFuncdef("bool array<T>::less(const T&in if_handle_then_const a, const T&in if_handle_then_const b)");
|
||||||
r = engine->RegisterObjectMethod("array<T>", "void sort(const less &in, uint startAt = 0, uint count = uint(-1))", asFUNCTION(ScriptArraySortCallback_Generic), asCALL_GENERIC); assert(r >= 0);
|
r = engine->RegisterObjectMethod("array<T>", "void sort(const less &in, uint startAt = 0, uint count = uint(-1))", asFUNCTION(ScriptArraySortCallback_Generic), asCALL_GENERIC); assert(r >= 0);
|
||||||
|
|
||||||
#if AS_USE_STLNAMES != 1 && AS_USE_ACCESSORS == 1
|
#if AS_USE_STLNAMES != 1 && AS_USE_ACCESSORS == 1
|
||||||
r = engine->RegisterObjectMethod("array<T>", "uint get_length() const property", asFUNCTION(ScriptArrayLength_Generic), asCALL_GENERIC); assert( r >= 0 );
|
r = engine->RegisterObjectMethod("array<T>", "uint get_length() const property", asFUNCTION(ScriptArrayLength_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||||
r = engine->RegisterObjectMethod("array<T>", "void set_length(uint) property", asFUNCTION(ScriptArrayResize_Generic), asCALL_GENERIC); assert( r >= 0 );
|
r = engine->RegisterObjectMethod("array<T>", "void set_length(uint) property", asFUNCTION(ScriptArrayResize_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||||
|
|
|
@ -124,6 +124,7 @@ protected:
|
||||||
void *GetArrayItemPointer(int index);
|
void *GetArrayItemPointer(int index);
|
||||||
void *GetDataPointer(void *buffer);
|
void *GetDataPointer(void *buffer);
|
||||||
void Copy(void *dst, void *src);
|
void Copy(void *dst, void *src);
|
||||||
|
void Swap(void *a, void *b);
|
||||||
void Precache();
|
void Precache();
|
||||||
bool CheckMaxSize(asUINT numElements);
|
bool CheckMaxSize(asUINT numElements);
|
||||||
void Resize(int delta, asUINT at);
|
void Resize(int delta, asUINT at);
|
||||||
|
|
|
@ -302,7 +302,7 @@ int CScriptBuilder::ProcessScriptSection(const char *script, unsigned int length
|
||||||
declaration.reserve(100);
|
declaration.reserve(100);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Then check for meta data and #include directives
|
// Then check for meta data and pre-processor directives
|
||||||
pos = 0;
|
pos = 0;
|
||||||
while( pos < modifiedScript.size() )
|
while( pos < modifiedScript.size() )
|
||||||
{
|
{
|
||||||
|
@ -313,10 +313,19 @@ int CScriptBuilder::ProcessScriptSection(const char *script, unsigned int length
|
||||||
pos += len;
|
pos += len;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
string token;
|
||||||
|
token.assign(&modifiedScript[pos], len);
|
||||||
|
|
||||||
#if AS_PROCESS_METADATA == 1
|
#if AS_PROCESS_METADATA == 1
|
||||||
// Check if class
|
// Skip possible decorators before class and interface declarations
|
||||||
if( currentClass == "" && modifiedScript.substr(pos,len) == "class" )
|
if (token == "shared" || token == "abstract" || token == "mixin" || token == "external")
|
||||||
|
{
|
||||||
|
pos += len;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if class or interface so the metadata for members can be gathered
|
||||||
|
if( currentClass == "" && (token == "class" || token == "interface") )
|
||||||
{
|
{
|
||||||
// Get the identifier after "class"
|
// Get the identifier after "class"
|
||||||
do
|
do
|
||||||
|
@ -362,15 +371,15 @@ int CScriptBuilder::ProcessScriptSection(const char *script, unsigned int length
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if end of class
|
// Check if end of class
|
||||||
if( currentClass != "" && modifiedScript[pos] == '}' )
|
if( currentClass != "" && token == "}" )
|
||||||
{
|
{
|
||||||
currentClass = "";
|
currentClass = "";
|
||||||
pos += len;
|
pos += len;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if namespace
|
// Check if namespace so the metadata for members can be gathered
|
||||||
if( modifiedScript.substr(pos,len) == "namespace" )
|
if( token == "namespace" )
|
||||||
{
|
{
|
||||||
// Get the identifier after "namespace"
|
// Get the identifier after "namespace"
|
||||||
do
|
do
|
||||||
|
@ -403,7 +412,7 @@ int CScriptBuilder::ProcessScriptSection(const char *script, unsigned int length
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if end of namespace
|
// Check if end of namespace
|
||||||
if( currentNamespace != "" && modifiedScript[pos] == '}' )
|
if( currentNamespace != "" && token == "}" )
|
||||||
{
|
{
|
||||||
size_t found = currentNamespace.rfind( "::" );
|
size_t found = currentNamespace.rfind( "::" );
|
||||||
if( found != string::npos )
|
if( found != string::npos )
|
||||||
|
@ -419,7 +428,7 @@ int CScriptBuilder::ProcessScriptSection(const char *script, unsigned int length
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is this the start of metadata?
|
// Is this the start of metadata?
|
||||||
if( modifiedScript[pos] == '[' )
|
if( token == "[" )
|
||||||
{
|
{
|
||||||
// Get the metadata string
|
// Get the metadata string
|
||||||
pos = ExtractMetadata(pos, metadata);
|
pos = ExtractMetadata(pos, metadata);
|
||||||
|
@ -438,37 +447,36 @@ int CScriptBuilder::ProcessScriptSection(const char *script, unsigned int length
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
// Is this a preprocessor directive?
|
// Is this a preprocessor directive?
|
||||||
if( modifiedScript[pos] == '#' && (pos + 1 < modifiedScript.size()) )
|
if( token == "#" && (pos + 1 < modifiedScript.size()) )
|
||||||
{
|
{
|
||||||
int start = pos++;
|
int start = pos++;
|
||||||
|
|
||||||
t = engine->ParseToken(&modifiedScript[pos], modifiedScript.size() - pos, &len);
|
t = engine->ParseToken(&modifiedScript[pos], modifiedScript.size() - pos, &len);
|
||||||
if( t == asTC_IDENTIFIER )
|
if (t == asTC_IDENTIFIER)
|
||||||
{
|
{
|
||||||
string token;
|
|
||||||
token.assign(&modifiedScript[pos], len);
|
token.assign(&modifiedScript[pos], len);
|
||||||
if( token == "include" )
|
if (token == "include")
|
||||||
{
|
{
|
||||||
pos += len;
|
pos += len;
|
||||||
t = engine->ParseToken(&modifiedScript[pos], modifiedScript.size() - pos, &len);
|
t = engine->ParseToken(&modifiedScript[pos], modifiedScript.size() - pos, &len);
|
||||||
if( t == asTC_WHITESPACE )
|
if (t == asTC_WHITESPACE)
|
||||||
{
|
{
|
||||||
pos += len;
|
pos += len;
|
||||||
t = engine->ParseToken(&modifiedScript[pos], modifiedScript.size() - pos, &len);
|
t = engine->ParseToken(&modifiedScript[pos], modifiedScript.size() - pos, &len);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( t == asTC_VALUE && len > 2 && (modifiedScript[pos] == '"' || modifiedScript[pos] == '\'') )
|
if (t == asTC_VALUE && len > 2 && (modifiedScript[pos] == '"' || modifiedScript[pos] == '\''))
|
||||||
{
|
{
|
||||||
// Get the include file
|
// Get the include file
|
||||||
string includefile;
|
string includefile;
|
||||||
includefile.assign(&modifiedScript[pos+1], len-2);
|
includefile.assign(&modifiedScript[pos + 1], len - 2);
|
||||||
pos += len;
|
pos += len;
|
||||||
|
|
||||||
// Store it for later processing
|
// Store it for later processing
|
||||||
includes.push_back(includefile);
|
includes.push_back(includefile);
|
||||||
|
|
||||||
// Overwrite the include directive with space characters to avoid compiler error
|
// Overwrite the include directive with space characters to avoid compiler error
|
||||||
OverwriteCode(start, pos-start);
|
OverwriteCode(start, pos - start);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (token == "pragma")
|
else if (token == "pragma")
|
||||||
|
@ -491,6 +499,19 @@ int CScriptBuilder::ProcessScriptSection(const char *script, unsigned int length
|
||||||
OverwriteCode(start, pos - start);
|
OverwriteCode(start, pos - start);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Check for lines starting with #!, e.g. shebang interpreter directive. These will be treated as comments and removed by the preprocessor
|
||||||
|
if (modifiedScript[pos] == '!')
|
||||||
|
{
|
||||||
|
// Read until the end of the line
|
||||||
|
pos += len;
|
||||||
|
for (; pos < modifiedScript.size() && modifiedScript[pos] != '\n'; pos++);
|
||||||
|
|
||||||
|
// Overwrite the directive with space characters to avoid compiler error
|
||||||
|
OverwriteCode(start, pos - start);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Don't search for metadata/includes within statement blocks or between tokens in statements
|
// Don't search for metadata/includes within statement blocks or between tokens in statements
|
||||||
else
|
else
|
||||||
|
|
|
@ -1140,7 +1140,6 @@ void RegisterScriptDictionary_Native(asIScriptEngine *engine)
|
||||||
// Same as deleteAll
|
// Same as deleteAll
|
||||||
r = engine->RegisterObjectMethod("dictionary", "void clear()", asMETHOD(CScriptDictionary,DeleteAll), asCALL_THISCALL); assert( r >= 0 );
|
r = engine->RegisterObjectMethod("dictionary", "void clear()", asMETHOD(CScriptDictionary,DeleteAll), asCALL_THISCALL); assert( r >= 0 );
|
||||||
#endif
|
#endif
|
||||||
(void)r;
|
|
||||||
|
|
||||||
// Cache some things the dictionary will need at runtime
|
// Cache some things the dictionary will need at runtime
|
||||||
SDictionaryCache::Setup(engine);
|
SDictionaryCache::Setup(engine);
|
||||||
|
@ -1209,7 +1208,6 @@ void RegisterScriptDictionary_Generic(asIScriptEngine *engine)
|
||||||
r = engine->RegisterObjectBehaviour("dictionary", asBEHAVE_ENUMREFS, "void f(int&in)", asFUNCTION(ScriptDictionaryEnumReferences_Generic), asCALL_GENERIC); assert( r >= 0 );
|
r = engine->RegisterObjectBehaviour("dictionary", asBEHAVE_ENUMREFS, "void f(int&in)", asFUNCTION(ScriptDictionaryEnumReferences_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||||
r = engine->RegisterObjectBehaviour("dictionary", asBEHAVE_RELEASEREFS, "void f(int&in)", asFUNCTION(ScriptDictionaryReleaseAllReferences_Generic), asCALL_GENERIC); assert( r >= 0 );
|
r = engine->RegisterObjectBehaviour("dictionary", asBEHAVE_RELEASEREFS, "void f(int&in)", asFUNCTION(ScriptDictionaryReleaseAllReferences_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||||
|
|
||||||
(void)r;
|
|
||||||
// Cache some things the dictionary will need at runtime
|
// Cache some things the dictionary will need at runtime
|
||||||
SDictionaryCache::Setup(engine);
|
SDictionaryCache::Setup(engine);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "scriptfilesystem.h"
|
#include "scriptfilesystem.h"
|
||||||
#include "../autowrapper/aswrappedcall.h"
|
#include "../autowrapper/aswrappedcall.h"
|
||||||
|
#include <string.h> // strstr()
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#include <direct.h> // _getcwd
|
#include <direct.h> // _getcwd
|
||||||
|
@ -383,6 +384,7 @@ asINT64 CScriptFileSystem::GetSize(const string &path) const
|
||||||
// - path not found
|
// - path not found
|
||||||
// - access denied
|
// - access denied
|
||||||
// TODO: Should be able to define the permissions for the directory
|
// TODO: Should be able to define the permissions for the directory
|
||||||
|
// TODO: Should support recursively creating directories
|
||||||
int CScriptFileSystem::MakeDir(const string &path)
|
int CScriptFileSystem::MakeDir(const string &path)
|
||||||
{
|
{
|
||||||
string search;
|
string search;
|
||||||
|
|
|
@ -222,9 +222,8 @@ void CScriptHandle::EnumReferences(asIScriptEngine *inEngine)
|
||||||
inEngine->GCEnumCallback(m_type);
|
inEngine->GCEnumCallback(m_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CScriptHandle::ReleaseReferences(asIScriptEngine *inEngine)
|
void CScriptHandle::ReleaseReferences(asIScriptEngine * /*inEngine*/)
|
||||||
{
|
{
|
||||||
(void)inEngine;
|
|
||||||
// Simply clear the content to release the references
|
// Simply clear the content to release the references
|
||||||
Set(0, 0);
|
Set(0, 0);
|
||||||
}
|
}
|
||||||
|
@ -250,7 +249,6 @@ void RegisterScriptHandle_Native(asIScriptEngine *engine)
|
||||||
r = engine->RegisterObjectMethod("ref", "ref &opHndlAssign(const ?&in)", asMETHOD(CScriptHandle, Assign), asCALL_THISCALL); assert( r >= 0 );
|
r = engine->RegisterObjectMethod("ref", "ref &opHndlAssign(const ?&in)", asMETHOD(CScriptHandle, Assign), asCALL_THISCALL); assert( r >= 0 );
|
||||||
r = engine->RegisterObjectMethod("ref", "bool opEquals(const ref &in) const", asMETHODPR(CScriptHandle, operator==, (const CScriptHandle &) const, bool), asCALL_THISCALL); assert( r >= 0 );
|
r = engine->RegisterObjectMethod("ref", "bool opEquals(const ref &in) const", asMETHODPR(CScriptHandle, operator==, (const CScriptHandle &) const, bool), asCALL_THISCALL); assert( r >= 0 );
|
||||||
r = engine->RegisterObjectMethod("ref", "bool opEquals(const ?&in) const", asMETHODPR(CScriptHandle, Equals, (void*, int) const, bool), asCALL_THISCALL); assert( r >= 0 );
|
r = engine->RegisterObjectMethod("ref", "bool opEquals(const ?&in) const", asMETHODPR(CScriptHandle, Equals, (void*, int) const, bool), asCALL_THISCALL); assert( r >= 0 );
|
||||||
(void)r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CScriptHandle_Construct_Generic(asIScriptGeneric *gen)
|
void CScriptHandle_Construct_Generic(asIScriptGeneric *gen)
|
||||||
|
@ -348,7 +346,6 @@ void RegisterScriptHandle_Generic(asIScriptEngine *engine)
|
||||||
r = engine->RegisterObjectMethod("ref", "ref &opHndlAssign(const ?&in)", asFUNCTION(CScriptHandle_AssignVar_Generic), asCALL_GENERIC); assert( r >= 0 );
|
r = engine->RegisterObjectMethod("ref", "ref &opHndlAssign(const ?&in)", asFUNCTION(CScriptHandle_AssignVar_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||||
r = engine->RegisterObjectMethod("ref", "bool opEquals(const ref &in) const", asFUNCTION(CScriptHandle_Equals_Generic), asCALL_GENERIC); assert( r >= 0 );
|
r = engine->RegisterObjectMethod("ref", "bool opEquals(const ref &in) const", asFUNCTION(CScriptHandle_Equals_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||||
r = engine->RegisterObjectMethod("ref", "bool opEquals(const ?&in) const", asFUNCTION(CScriptHandle_EqualsVar_Generic), asCALL_GENERIC); assert( r >= 0 );
|
r = engine->RegisterObjectMethod("ref", "bool opEquals(const ?&in) const", asFUNCTION(CScriptHandle_EqualsVar_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||||
(void)r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegisterScriptHandle(asIScriptEngine *engine)
|
void RegisterScriptHandle(asIScriptEngine *engine)
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include "../autowrapper/aswrappedcall.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -980,9 +981,16 @@ void RegisterExceptionRoutines(asIScriptEngine *engine)
|
||||||
// The string type must be available
|
// The string type must be available
|
||||||
assert(engine->GetTypeInfoByDecl("string"));
|
assert(engine->GetTypeInfoByDecl("string"));
|
||||||
|
|
||||||
r = engine->RegisterGlobalFunction("void throw(const string &in)", asFUNCTION(ScriptThrow), asCALL_CDECL); assert(r >= 0);
|
if (strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") == 0)
|
||||||
r = engine->RegisterGlobalFunction("string getExceptionInfo()", asFUNCTION(ScriptGetExceptionInfo), asCALL_CDECL); assert(r >= 0);
|
{
|
||||||
(void)r;
|
r = engine->RegisterGlobalFunction("void throw(const string &in)", asFUNCTION(ScriptThrow), asCALL_CDECL); assert(r >= 0);
|
||||||
|
r = engine->RegisterGlobalFunction("string getExceptionInfo()", asFUNCTION(ScriptGetExceptionInfo), asCALL_CDECL); assert(r >= 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r = engine->RegisterGlobalFunction("void throw(const string &in)", WRAP_FN(ScriptThrow), asCALL_GENERIC); assert(r >= 0);
|
||||||
|
r = engine->RegisterGlobalFunction("string getExceptionInfo()", WRAP_FN(ScriptGetExceptionInfo), asCALL_GENERIC); assert(r >= 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
END_AS_NAMESPACE
|
END_AS_NAMESPACE
|
||||||
|
|
|
@ -72,45 +72,27 @@ double fraction(double v)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<typename T, typename F>
|
|
||||||
struct alias_cast_t
|
|
||||||
{
|
|
||||||
union
|
|
||||||
{
|
|
||||||
F raw;
|
|
||||||
T data;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// As AngelScript doesn't allow bitwise manipulation of float types we'll provide a couple of
|
// As AngelScript doesn't allow bitwise manipulation of float types we'll provide a couple of
|
||||||
// functions for converting float values to IEEE 754 formatted values etc. This also allow us to
|
// functions for converting float values to IEEE 754 formatted values etc. This also allow us to
|
||||||
// provide a platform agnostic representation to the script so the scripts don't have to worry
|
// provide a platform agnostic representation to the script so the scripts don't have to worry
|
||||||
// about whether the CPU uses IEEE 754 floats or some other representation
|
// about whether the CPU uses IEEE 754 floats or some other representation
|
||||||
float fpFromIEEE(asUINT raw)
|
float fpFromIEEE(asUINT raw)
|
||||||
{
|
{
|
||||||
// TODO: Identify CPU family to provide proper conversion
|
// TODO: Identify CPU family to provide proper conversion
|
||||||
// if the CPU doesn't natively use IEEE style floats
|
// if the CPU doesn't natively use IEEE style floats
|
||||||
alias_cast_t<asUINT, float> t;
|
return *reinterpret_cast<float*>(&raw);
|
||||||
t.raw = raw;
|
|
||||||
return t.data;
|
|
||||||
}
|
}
|
||||||
asUINT fpToIEEE(float fp)
|
asUINT fpToIEEE(float fp)
|
||||||
{
|
{
|
||||||
alias_cast_t<float, asUINT> t;
|
return *reinterpret_cast<asUINT*>(&fp);
|
||||||
t.raw = fp;
|
|
||||||
return t.data;
|
|
||||||
}
|
}
|
||||||
double fpFromIEEE(asQWORD raw)
|
double fpFromIEEE(asQWORD raw)
|
||||||
{
|
{
|
||||||
alias_cast_t<asQWORD, double> t;
|
return *reinterpret_cast<double*>(&raw);
|
||||||
t.raw = raw;
|
|
||||||
return t.data;
|
|
||||||
}
|
}
|
||||||
asQWORD fpToIEEE(double fp)
|
asQWORD fpToIEEE(double fp)
|
||||||
{
|
{
|
||||||
alias_cast_t<double, asQWORD> t;
|
return *reinterpret_cast<asQWORD*>(&fp);
|
||||||
t.raw = fp;
|
|
||||||
return t.data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// closeTo() is used to determine if the binary representation of two numbers are
|
// closeTo() is used to determine if the binary representation of two numbers are
|
||||||
|
@ -214,7 +196,6 @@ void RegisterScriptMath_Native(asIScriptEngine *engine)
|
||||||
r = engine->RegisterGlobalFunction("double floor(double)", asFUNCTIONPR(floor, (double), double), asCALL_CDECL); assert( r >= 0 );
|
r = engine->RegisterGlobalFunction("double floor(double)", asFUNCTIONPR(floor, (double), double), asCALL_CDECL); assert( r >= 0 );
|
||||||
r = engine->RegisterGlobalFunction("double fraction(double)", asFUNCTIONPR(fraction, (double), double), asCALL_CDECL); assert( r >= 0 );
|
r = engine->RegisterGlobalFunction("double fraction(double)", asFUNCTIONPR(fraction, (double), double), asCALL_CDECL); assert( r >= 0 );
|
||||||
#endif
|
#endif
|
||||||
(void)r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if AS_USE_FLOAT
|
#if AS_USE_FLOAT
|
||||||
|
@ -351,7 +332,6 @@ void RegisterScriptMath_Generic(asIScriptEngine *engine)
|
||||||
r = engine->RegisterGlobalFunction("double floor(double)", asFUNCTION(floor_generic), asCALL_GENERIC); assert( r >= 0 );
|
r = engine->RegisterGlobalFunction("double floor(double)", asFUNCTION(floor_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||||
r = engine->RegisterGlobalFunction("double fraction(double)", asFUNCTION(fraction_generic), asCALL_GENERIC); assert( r >= 0 );
|
r = engine->RegisterGlobalFunction("double fraction(double)", asFUNCTION(fraction_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||||
#endif
|
#endif
|
||||||
(void)r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegisterScriptMath(asIScriptEngine *engine)
|
void RegisterScriptMath(asIScriptEngine *engine)
|
||||||
|
|
|
@ -34,8 +34,9 @@ static CScriptArray *StringSplit(const string &delim, const string &str)
|
||||||
CScriptArray *array = CScriptArray::Create(arrayType);
|
CScriptArray *array = CScriptArray::Create(arrayType);
|
||||||
|
|
||||||
// Find the existence of the delimiter in the input string
|
// Find the existence of the delimiter in the input string
|
||||||
int pos = 0, prev = 0, count = 0;
|
size_t pos = 0, prev = 0;
|
||||||
while( (pos = (int)str.find(delim, prev)) != (int)string::npos )
|
asUINT count = 0;
|
||||||
|
while( (pos = str.find(delim, prev)) != string::npos )
|
||||||
{
|
{
|
||||||
// Add the part to the array
|
// Add the part to the array
|
||||||
array->Resize(array->GetSize()+1);
|
array->Resize(array->GetSize()+1);
|
||||||
|
@ -43,7 +44,7 @@ static CScriptArray *StringSplit(const string &delim, const string &str)
|
||||||
|
|
||||||
// Find the next part
|
// Find the next part
|
||||||
count++;
|
count++;
|
||||||
prev = pos + (int)delim.length();
|
prev = pos + delim.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the remaining part
|
// Add the remaining part
|
||||||
|
|
|
@ -226,7 +226,7 @@ void RegisterScriptWeakRef_Native(asIScriptEngine *engine)
|
||||||
r = engine->RegisterObjectType("weakref<class T>", sizeof(CScriptWeakRef), asOBJ_VALUE | asOBJ_ASHANDLE | asOBJ_TEMPLATE | asOBJ_APP_CLASS_DAK); assert( r >= 0 );
|
r = engine->RegisterObjectType("weakref<class T>", sizeof(CScriptWeakRef), asOBJ_VALUE | asOBJ_ASHANDLE | asOBJ_TEMPLATE | asOBJ_APP_CLASS_DAK); assert( r >= 0 );
|
||||||
|
|
||||||
r = engine->RegisterObjectBehaviour("weakref<T>", asBEHAVE_CONSTRUCT, "void f(int&in)", asFUNCTION(ScriptWeakRefConstruct), asCALL_CDECL_OBJLAST); assert( r>= 0 );
|
r = engine->RegisterObjectBehaviour("weakref<T>", asBEHAVE_CONSTRUCT, "void f(int&in)", asFUNCTION(ScriptWeakRefConstruct), asCALL_CDECL_OBJLAST); assert( r>= 0 );
|
||||||
r = engine->RegisterObjectBehaviour("weakref<T>", asBEHAVE_CONSTRUCT, "void f(int&in, T@+)", asFUNCTION(ScriptWeakRefConstruct2), asCALL_CDECL_OBJLAST); assert( r>= 0 );
|
r = engine->RegisterObjectBehaviour("weakref<T>", asBEHAVE_CONSTRUCT, "void f(int&in, T@+) explicit", asFUNCTION(ScriptWeakRefConstruct2), asCALL_CDECL_OBJLAST); assert( r>= 0 );
|
||||||
r = engine->RegisterObjectBehaviour("weakref<T>", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(ScriptWeakRefDestruct), asCALL_CDECL_OBJLAST); assert( r >= 0 );
|
r = engine->RegisterObjectBehaviour("weakref<T>", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(ScriptWeakRefDestruct), asCALL_CDECL_OBJLAST); assert( r >= 0 );
|
||||||
r = engine->RegisterObjectBehaviour("weakref<T>", asBEHAVE_TEMPLATE_CALLBACK, "bool f(int&in, bool&out)", asFUNCTION(ScriptWeakRefTemplateCallback), asCALL_CDECL); assert( r >= 0 );
|
r = engine->RegisterObjectBehaviour("weakref<T>", asBEHAVE_TEMPLATE_CALLBACK, "bool f(int&in, bool&out)", asFUNCTION(ScriptWeakRefTemplateCallback), asCALL_CDECL); assert( r >= 0 );
|
||||||
|
|
||||||
|
@ -242,7 +242,7 @@ void RegisterScriptWeakRef_Native(asIScriptEngine *engine)
|
||||||
r = engine->RegisterObjectType("const_weakref<class T>", sizeof(CScriptWeakRef), asOBJ_VALUE | asOBJ_ASHANDLE | asOBJ_TEMPLATE | asOBJ_APP_CLASS_DAK); assert( r >= 0 );
|
r = engine->RegisterObjectType("const_weakref<class T>", sizeof(CScriptWeakRef), asOBJ_VALUE | asOBJ_ASHANDLE | asOBJ_TEMPLATE | asOBJ_APP_CLASS_DAK); assert( r >= 0 );
|
||||||
|
|
||||||
r = engine->RegisterObjectBehaviour("const_weakref<T>", asBEHAVE_CONSTRUCT, "void f(int&in)", asFUNCTION(ScriptWeakRefConstruct), asCALL_CDECL_OBJLAST); assert( r>= 0 );
|
r = engine->RegisterObjectBehaviour("const_weakref<T>", asBEHAVE_CONSTRUCT, "void f(int&in)", asFUNCTION(ScriptWeakRefConstruct), asCALL_CDECL_OBJLAST); assert( r>= 0 );
|
||||||
r = engine->RegisterObjectBehaviour("const_weakref<T>", asBEHAVE_CONSTRUCT, "void f(int&in, const T@+)", asFUNCTION(ScriptWeakRefConstruct2), asCALL_CDECL_OBJLAST); assert( r>= 0 );
|
r = engine->RegisterObjectBehaviour("const_weakref<T>", asBEHAVE_CONSTRUCT, "void f(int&in, const T@+) explicit", asFUNCTION(ScriptWeakRefConstruct2), asCALL_CDECL_OBJLAST); assert( r>= 0 );
|
||||||
r = engine->RegisterObjectBehaviour("const_weakref<T>", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(ScriptWeakRefDestruct), asCALL_CDECL_OBJLAST); assert( r >= 0 );
|
r = engine->RegisterObjectBehaviour("const_weakref<T>", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(ScriptWeakRefDestruct), asCALL_CDECL_OBJLAST); assert( r >= 0 );
|
||||||
r = engine->RegisterObjectBehaviour("const_weakref<T>", asBEHAVE_TEMPLATE_CALLBACK, "bool f(int&in, bool&out)", asFUNCTION(ScriptWeakRefTemplateCallback), asCALL_CDECL); assert( r >= 0 );
|
r = engine->RegisterObjectBehaviour("const_weakref<T>", asBEHAVE_TEMPLATE_CALLBACK, "bool f(int&in, bool&out)", asFUNCTION(ScriptWeakRefTemplateCallback), asCALL_CDECL); assert( r >= 0 );
|
||||||
|
|
||||||
|
@ -332,7 +332,7 @@ void RegisterScriptWeakRef_Generic(asIScriptEngine *engine)
|
||||||
r = engine->RegisterObjectType("weakref<class T>", sizeof(CScriptWeakRef), asOBJ_VALUE | asOBJ_ASHANDLE | asOBJ_TEMPLATE | asOBJ_APP_CLASS_DAK); assert( r >= 0 );
|
r = engine->RegisterObjectType("weakref<class T>", sizeof(CScriptWeakRef), asOBJ_VALUE | asOBJ_ASHANDLE | asOBJ_TEMPLATE | asOBJ_APP_CLASS_DAK); assert( r >= 0 );
|
||||||
|
|
||||||
r = engine->RegisterObjectBehaviour("weakref<T>", asBEHAVE_CONSTRUCT, "void f(int&in)", asFUNCTION(ScriptWeakRefConstruct_Generic), asCALL_GENERIC); assert( r>= 0 );
|
r = engine->RegisterObjectBehaviour("weakref<T>", asBEHAVE_CONSTRUCT, "void f(int&in)", asFUNCTION(ScriptWeakRefConstruct_Generic), asCALL_GENERIC); assert( r>= 0 );
|
||||||
r = engine->RegisterObjectBehaviour("weakref<T>", asBEHAVE_CONSTRUCT, "void f(int&in, T@+)", asFUNCTION(ScriptWeakRefConstruct2_Generic), asCALL_GENERIC); assert( r>= 0 );
|
r = engine->RegisterObjectBehaviour("weakref<T>", asBEHAVE_CONSTRUCT, "void f(int&in, T@+) explicit", asFUNCTION(ScriptWeakRefConstruct2_Generic), asCALL_GENERIC); assert( r>= 0 );
|
||||||
r = engine->RegisterObjectBehaviour("weakref<T>", asBEHAVE_TEMPLATE_CALLBACK, "bool f(int&in, bool&out)", asFUNCTION(ScriptWeakRefTemplateCallback_Generic), asCALL_GENERIC); assert( r >= 0 );
|
r = engine->RegisterObjectBehaviour("weakref<T>", asBEHAVE_TEMPLATE_CALLBACK, "bool f(int&in, bool&out)", asFUNCTION(ScriptWeakRefTemplateCallback_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||||
r = engine->RegisterObjectBehaviour("weakref<T>", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(ScriptWeakRefDestruct_Generic), asCALL_GENERIC); assert( r >= 0 );
|
r = engine->RegisterObjectBehaviour("weakref<T>", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(ScriptWeakRefDestruct_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||||
|
|
||||||
|
@ -348,7 +348,7 @@ void RegisterScriptWeakRef_Generic(asIScriptEngine *engine)
|
||||||
r = engine->RegisterObjectType("const_weakref<class T>", sizeof(CScriptWeakRef), asOBJ_VALUE | asOBJ_ASHANDLE | asOBJ_TEMPLATE | asOBJ_APP_CLASS_DAK); assert( r >= 0 );
|
r = engine->RegisterObjectType("const_weakref<class T>", sizeof(CScriptWeakRef), asOBJ_VALUE | asOBJ_ASHANDLE | asOBJ_TEMPLATE | asOBJ_APP_CLASS_DAK); assert( r >= 0 );
|
||||||
|
|
||||||
r = engine->RegisterObjectBehaviour("const_weakref<T>", asBEHAVE_CONSTRUCT, "void f(int&in)", asFUNCTION(ScriptWeakRefConstruct_Generic), asCALL_GENERIC); assert( r>= 0 );
|
r = engine->RegisterObjectBehaviour("const_weakref<T>", asBEHAVE_CONSTRUCT, "void f(int&in)", asFUNCTION(ScriptWeakRefConstruct_Generic), asCALL_GENERIC); assert( r>= 0 );
|
||||||
r = engine->RegisterObjectBehaviour("const_weakref<T>", asBEHAVE_CONSTRUCT, "void f(int&in, const T@+)", asFUNCTION(ScriptWeakRefConstruct2_Generic), asCALL_GENERIC); assert( r>= 0 );
|
r = engine->RegisterObjectBehaviour("const_weakref<T>", asBEHAVE_CONSTRUCT, "void f(int&in, const T@+) explicit", asFUNCTION(ScriptWeakRefConstruct2_Generic), asCALL_GENERIC); assert( r>= 0 );
|
||||||
r = engine->RegisterObjectBehaviour("const_weakref<T>", asBEHAVE_TEMPLATE_CALLBACK, "bool f(int&in, bool&out)", asFUNCTION(ScriptWeakRefTemplateCallback_Generic), asCALL_GENERIC); assert( r >= 0 );
|
r = engine->RegisterObjectBehaviour("const_weakref<T>", asBEHAVE_TEMPLATE_CALLBACK, "bool f(int&in, bool&out)", asFUNCTION(ScriptWeakRefTemplateCallback_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||||
r = engine->RegisterObjectBehaviour("const_weakref<T>", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(ScriptWeakRefDestruct_Generic), asCALL_GENERIC); assert( r >= 0 );
|
r = engine->RegisterObjectBehaviour("const_weakref<T>", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(ScriptWeakRefDestruct_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
#include "as_atomic.h"
|
#include "as_atomic.h"
|
||||||
|
|
||||||
BEGIN_AS_NAMESPACE
|
BEGIN_AS_NAMESPACE
|
||||||
const asUINT MAX_VALUE = 100000000;
|
|
||||||
|
|
||||||
asCAtomic::asCAtomic()
|
asCAtomic::asCAtomic()
|
||||||
{
|
{
|
||||||
|
@ -48,7 +47,7 @@ asDWORD asCAtomic::get() const
|
||||||
{
|
{
|
||||||
// A very high ref count is highly unlikely. It most likely a problem with
|
// A very high ref count is highly unlikely. It most likely a problem with
|
||||||
// memory that has been overwritten or is being accessed after it was deleted.
|
// memory that has been overwritten or is being accessed after it was deleted.
|
||||||
asASSERT(value < MAX_VALUE);
|
asASSERT(value < 1000000);
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -57,7 +56,7 @@ void asCAtomic::set(asDWORD val)
|
||||||
{
|
{
|
||||||
// A very high ref count is highly unlikely. It most likely a problem with
|
// A very high ref count is highly unlikely. It most likely a problem with
|
||||||
// memory that has been overwritten or is being accessed after it was deleted.
|
// memory that has been overwritten or is being accessed after it was deleted.
|
||||||
asASSERT(value < MAX_VALUE);
|
asASSERT(value < 1000000);
|
||||||
|
|
||||||
value = val;
|
value = val;
|
||||||
}
|
}
|
||||||
|
@ -66,7 +65,7 @@ asDWORD asCAtomic::atomicInc()
|
||||||
{
|
{
|
||||||
// A very high ref count is highly unlikely. It most likely a problem with
|
// A very high ref count is highly unlikely. It most likely a problem with
|
||||||
// memory that has been overwritten or is being accessed after it was deleted.
|
// memory that has been overwritten or is being accessed after it was deleted.
|
||||||
asASSERT(value < MAX_VALUE);
|
asASSERT(value < 1000000);
|
||||||
|
|
||||||
return asAtomicInc((int&)value);
|
return asAtomicInc((int&)value);
|
||||||
}
|
}
|
||||||
|
@ -75,7 +74,7 @@ asDWORD asCAtomic::atomicDec()
|
||||||
{
|
{
|
||||||
// A very high ref count is highly unlikely. It most likely a problem with
|
// A very high ref count is highly unlikely. It most likely a problem with
|
||||||
// memory that has been overwritten or is being accessed after it was deleted.
|
// memory that has been overwritten or is being accessed after it was deleted.
|
||||||
asASSERT(value < MAX_VALUE);
|
asASSERT(value < 1000000);
|
||||||
|
|
||||||
return asAtomicDec((int&)value);
|
return asAtomicDec((int&)value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
AngelCode Scripting Library
|
AngelCode Scripting Library
|
||||||
Copyright (c) 2003-2020 Andreas Jonsson
|
Copyright (c) 2003-2021 Andreas Jonsson
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any
|
warranty. In no event will the authors be held liable for any
|
||||||
|
@ -1602,8 +1602,29 @@ int asCBuilder::CheckNameConflict(const char *name, asCScriptNode *node, asCScri
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef AS_NO_COMPILER
|
#ifndef AS_NO_COMPILER
|
||||||
// Check against class types
|
// Check against interface types
|
||||||
asUINT n;
|
asUINT n;
|
||||||
|
for (n = 0; n < interfaceDeclarations.GetLength(); n++)
|
||||||
|
{
|
||||||
|
if (interfaceDeclarations[n]->name == name &&
|
||||||
|
interfaceDeclarations[n]->typeInfo->nameSpace == ns)
|
||||||
|
{
|
||||||
|
if (code)
|
||||||
|
{
|
||||||
|
asCString str;
|
||||||
|
if (ns->name != "")
|
||||||
|
str = ns->name + "::" + name;
|
||||||
|
else
|
||||||
|
str = name;
|
||||||
|
str.Format(TXT_NAME_CONFLICT_s_INTF, str.AddressOf());
|
||||||
|
WriteError(str, code, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check against class types
|
||||||
for( n = 0; n < classDeclarations.GetLength(); n++ )
|
for( n = 0; n < classDeclarations.GetLength(); n++ )
|
||||||
{
|
{
|
||||||
if( classDeclarations[n]->name == name &&
|
if( classDeclarations[n]->name == name &&
|
||||||
|
@ -2080,10 +2101,12 @@ int asCBuilder::RegisterMixinClass(asCScriptNode *node, asCScriptCode *file, asS
|
||||||
|
|
||||||
asCScriptNode *n = cl->firstChild;
|
asCScriptNode *n = cl->firstChild;
|
||||||
|
|
||||||
// Skip potential 'final' and 'shared' tokens
|
// Skip potential decorator tokens
|
||||||
while( n->tokenType == ttIdentifier &&
|
while( n->tokenType == ttIdentifier &&
|
||||||
(file->TokenEquals(n->tokenPos, n->tokenLength, FINAL_TOKEN) ||
|
(file->TokenEquals(n->tokenPos, n->tokenLength, FINAL_TOKEN) ||
|
||||||
file->TokenEquals(n->tokenPos, n->tokenLength, SHARED_TOKEN)) )
|
file->TokenEquals(n->tokenPos, n->tokenLength, SHARED_TOKEN) ||
|
||||||
|
file->TokenEquals(n->tokenPos, n->tokenLength, ABSTRACT_TOKEN) ||
|
||||||
|
file->TokenEquals(n->tokenPos, n->tokenLength, EXTERNAL_TOKEN)) )
|
||||||
{
|
{
|
||||||
// Report error, because mixin class cannot be final or shared
|
// Report error, because mixin class cannot be final or shared
|
||||||
asCString msg;
|
asCString msg;
|
||||||
|
@ -2921,7 +2944,8 @@ void asCBuilder::CompileInterfaces()
|
||||||
// If any of the derived interfaces are found after this interface, then move this to the end of the list
|
// If any of the derived interfaces are found after this interface, then move this to the end of the list
|
||||||
for( asUINT m = n+1; m < interfaceDeclarations.GetLength(); m++ )
|
for( asUINT m = n+1; m < interfaceDeclarations.GetLength(); m++ )
|
||||||
{
|
{
|
||||||
if( intfType->Implements(interfaceDeclarations[m]->typeInfo) )
|
if( intfType != interfaceDeclarations[m]->typeInfo &&
|
||||||
|
intfType->Implements(interfaceDeclarations[m]->typeInfo) )
|
||||||
{
|
{
|
||||||
interfaceDeclarations.RemoveIndex(n);
|
interfaceDeclarations.RemoveIndex(n);
|
||||||
interfaceDeclarations.PushLast(intfDecl);
|
interfaceDeclarations.PushLast(intfDecl);
|
||||||
|
@ -4762,7 +4786,7 @@ int asCBuilder::RegisterScriptFunctionFromNode(asCScriptNode *node, asCScriptCod
|
||||||
return RegisterScriptFunction(node, file, objType, isInterface, isGlobalFunction, ns, isExistingShared, isMixin, name, returnType, parameterNames, parameterTypes, inOutFlags, defaultArgs, funcTraits);
|
return RegisterScriptFunction(node, file, objType, isInterface, isGlobalFunction, ns, isExistingShared, isMixin, name, returnType, parameterNames, parameterTypes, inOutFlags, defaultArgs, funcTraits);
|
||||||
}
|
}
|
||||||
|
|
||||||
asCScriptFunction *asCBuilder::RegisterLambda(asCScriptNode *node, asCScriptCode *file, asCScriptFunction *funcDef, const asCString &name, asSNameSpace *ns)
|
asCScriptFunction *asCBuilder::RegisterLambda(asCScriptNode *node, asCScriptCode *file, asCScriptFunction *funcDef, const asCString &name, asSNameSpace *ns, bool isShared)
|
||||||
{
|
{
|
||||||
// Get the parameter names from the node
|
// Get the parameter names from the node
|
||||||
asCArray<asCString> parameterNames;
|
asCArray<asCString> parameterNames;
|
||||||
|
@ -4785,7 +4809,9 @@ asCScriptFunction *asCBuilder::RegisterLambda(asCScriptNode *node, asCScriptCode
|
||||||
|
|
||||||
// Get the return and parameter types from the funcDef
|
// Get the return and parameter types from the funcDef
|
||||||
asCString funcName = name;
|
asCString funcName = name;
|
||||||
int r = RegisterScriptFunction(args, file, 0, 0, true, ns, false, false, funcName, funcDef->returnType, parameterNames, funcDef->parameterTypes, funcDef->inOutFlags, defaultArgs, asSFunctionTraits());
|
asSFunctionTraits traits;
|
||||||
|
traits.SetTrait(asTRAIT_SHARED, isShared);
|
||||||
|
int r = RegisterScriptFunction(args, file, 0, 0, true, ns, false, false, funcName, funcDef->returnType, parameterNames, funcDef->parameterTypes, funcDef->inOutFlags, defaultArgs, traits);
|
||||||
if( r < 0 )
|
if( r < 0 )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -5470,7 +5496,7 @@ void asCBuilder::GetObjectMethodDescriptions(const char *name, asCObjectType *ob
|
||||||
// TODO: child funcdef: A scope can include a template type, e.g. array<ns::type>
|
// TODO: child funcdef: A scope can include a template type, e.g. array<ns::type>
|
||||||
int n = scope.FindLast("::");
|
int n = scope.FindLast("::");
|
||||||
asCString className = n >= 0 ? scope.SubString(n+2) : scope;
|
asCString className = n >= 0 ? scope.SubString(n+2) : scope;
|
||||||
asCString nsName = n >= 0 ? scope.SubString(0, n) : "";
|
asCString nsName = n >= 0 ? scope.SubString(0, n) : asCString("");
|
||||||
|
|
||||||
// If a namespace was specifically defined, then this must be used
|
// If a namespace was specifically defined, then this must be used
|
||||||
asSNameSpace *ns = 0;
|
asSNameSpace *ns = 0;
|
||||||
|
@ -5954,6 +5980,19 @@ asCDataType asCBuilder::CreateDataTypeFromNode(asCScriptNode *node, asCScriptCod
|
||||||
{
|
{
|
||||||
if( n->tokenType == ttOpenBracket )
|
if( n->tokenType == ttOpenBracket )
|
||||||
{
|
{
|
||||||
|
if (isImplicitHandle)
|
||||||
|
{
|
||||||
|
// Make the type a handle
|
||||||
|
if (dt.MakeHandle(true, acceptHandleForScope) < 0)
|
||||||
|
{
|
||||||
|
if (reportError)
|
||||||
|
WriteError(TXT_OBJECT_HANDLE_NOT_SUPPORTED, file, n);
|
||||||
|
if (isValid)
|
||||||
|
*isValid = false;
|
||||||
|
}
|
||||||
|
isImplicitHandle = false;
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure the sub type can be instantiated
|
// Make sure the sub type can be instantiated
|
||||||
if( !dt.CanBeInstantiated() )
|
if( !dt.CanBeInstantiated() )
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
AngelCode Scripting Library
|
AngelCode Scripting Library
|
||||||
Copyright (c) 2003-2019 Andreas Jonsson
|
Copyright (c) 2003-2021 Andreas Jonsson
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any
|
warranty. In no event will the authors be held liable for any
|
||||||
|
@ -217,7 +217,7 @@ protected:
|
||||||
int RegisterEnum(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
|
int RegisterEnum(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
|
||||||
int RegisterTypedef(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
|
int RegisterTypedef(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
|
||||||
int RegisterFuncDef(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns, asCObjectType *parent);
|
int RegisterFuncDef(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns, asCObjectType *parent);
|
||||||
asCScriptFunction *RegisterLambda(asCScriptNode *node, asCScriptCode *file, asCScriptFunction *funcDef, const asCString &name, asSNameSpace *ns);
|
asCScriptFunction *RegisterLambda(asCScriptNode *node, asCScriptCode *file, asCScriptFunction *funcDef, const asCString &name, asSNameSpace *ns, bool isShared);
|
||||||
void CompleteFuncDef(sFuncDef *funcDef);
|
void CompleteFuncDef(sFuncDef *funcDef);
|
||||||
void CompileInterfaces();
|
void CompileInterfaces();
|
||||||
void CompileClasses(asUINT originalNumTempl);
|
void CompileClasses(asUINT originalNumTempl);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
AngelCode Scripting Library
|
AngelCode Scripting Library
|
||||||
Copyright (c) 2003-2020 Andreas Jonsson
|
Copyright (c) 2003-2021 Andreas Jonsson
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any
|
warranty. In no event will the authors be held liable for any
|
||||||
|
@ -55,8 +55,7 @@ BEGIN_AS_NAMESPACE
|
||||||
|
|
||||||
int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv, void *auxiliary, asSSystemFunctionInterface *internal)
|
int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv, void *auxiliary, asSSystemFunctionInterface *internal)
|
||||||
{
|
{
|
||||||
memset(internal, 0, sizeof(asSSystemFunctionInterface));
|
internal->Clear();
|
||||||
|
|
||||||
internal->func = ptr.ptr.f.func;
|
internal->func = ptr.ptr.f.func;
|
||||||
internal->auxiliary = 0;
|
internal->auxiliary = 0;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
AngelCode Scripting Library
|
AngelCode Scripting Library
|
||||||
Copyright (c) 2003-2020 Andreas Jonsson
|
Copyright (c) 2003-2021 Andreas Jonsson
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any
|
warranty. In no event will the authors be held liable for any
|
||||||
|
@ -119,13 +119,35 @@ struct asSSystemFunctionInterface
|
||||||
};
|
};
|
||||||
asCArray<SClean> cleanArgs;
|
asCArray<SClean> cleanArgs;
|
||||||
|
|
||||||
asSSystemFunctionInterface() : func(0), baseOffset(0), callConv(ICC_GENERIC_FUNC), hostReturnInMemory(false), hostReturnFloat(false), hostReturnSize(0), paramSize(0), takesObjByVal(false), returnAutoHandle(false), compositeOffset(0), isCompositeIndirect(false), auxiliary(0) {}
|
asSSystemFunctionInterface()
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
}
|
||||||
|
|
||||||
asSSystemFunctionInterface(const asSSystemFunctionInterface &in)
|
asSSystemFunctionInterface(const asSSystemFunctionInterface &in)
|
||||||
{
|
{
|
||||||
*this = in;
|
*this = in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
func = 0;
|
||||||
|
baseOffset = 0;
|
||||||
|
callConv = ICC_GENERIC_FUNC;
|
||||||
|
hostReturnInMemory = false;
|
||||||
|
hostReturnFloat = false;
|
||||||
|
hostReturnSize = 0;
|
||||||
|
paramSize = 0;
|
||||||
|
takesObjByVal = false;
|
||||||
|
returnAutoHandle = false;
|
||||||
|
compositeOffset = 0;
|
||||||
|
isCompositeIndirect = false;
|
||||||
|
auxiliary = 0;
|
||||||
|
|
||||||
|
paramAutoHandles.SetLength(0);
|
||||||
|
cleanArgs.SetLength(0);
|
||||||
|
}
|
||||||
|
|
||||||
asSSystemFunctionInterface &operator=(const asSSystemFunctionInterface &in)
|
asSSystemFunctionInterface &operator=(const asSSystemFunctionInterface &in)
|
||||||
{
|
{
|
||||||
func = in.func;
|
func = in.func;
|
||||||
|
@ -136,12 +158,14 @@ struct asSSystemFunctionInterface
|
||||||
hostReturnSize = in.hostReturnSize;
|
hostReturnSize = in.hostReturnSize;
|
||||||
paramSize = in.paramSize;
|
paramSize = in.paramSize;
|
||||||
takesObjByVal = in.takesObjByVal;
|
takesObjByVal = in.takesObjByVal;
|
||||||
paramAutoHandles = in.paramAutoHandles;
|
|
||||||
returnAutoHandle = in.returnAutoHandle;
|
returnAutoHandle = in.returnAutoHandle;
|
||||||
compositeOffset = in.compositeOffset;
|
compositeOffset = in.compositeOffset;
|
||||||
isCompositeIndirect = in.isCompositeIndirect;
|
isCompositeIndirect = in.isCompositeIndirect;
|
||||||
auxiliary = in.auxiliary;
|
auxiliary = in.auxiliary;
|
||||||
|
|
||||||
cleanArgs = in.cleanArgs;
|
cleanArgs = in.cleanArgs;
|
||||||
|
paramAutoHandles = in.paramAutoHandles;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
AngelCode Scripting Library
|
AngelCode Scripting Library
|
||||||
Copyright (c) 2020-2020 Andreas Jonsson
|
Copyright (c) 2020-2021 Andreas Jonsson
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any
|
warranty. In no event will the authors be held liable for any
|
||||||
|
@ -110,7 +110,7 @@ static inline bool IsRegisterHFA(const asCDataType &type)
|
||||||
|
|
||||||
if( typeInfo == nullptr ||
|
if( typeInfo == nullptr ||
|
||||||
(typeInfo->flags & asOBJ_APP_CLASS_ALLFLOATS) == 0 ||
|
(typeInfo->flags & asOBJ_APP_CLASS_ALLFLOATS) == 0 ||
|
||||||
type.IsObjectHandle() && type.IsReference() )
|
type.IsObjectHandle() || type.IsReference() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const bool doubles = (typeInfo->flags & asOBJ_APP_CLASS_ALIGN8) != 0;
|
const bool doubles = (typeInfo->flags & asOBJ_APP_CLASS_ALIGN8) != 0;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// AngelCode Scripting Library
|
// AngelCode Scripting Library
|
||||||
// Copyright (c) 2020-2020 Andreas Jonsson
|
// Copyright (c) 2020-2021 Andreas Jonsson
|
||||||
//
|
//
|
||||||
// This software is provided 'as-is', without any express or implied
|
// This software is provided 'as-is', without any express or implied
|
||||||
// warranty. In no event will the authors be held liable for any
|
// warranty. In no event will the authors be held liable for any
|
||||||
|
@ -35,6 +35,10 @@
|
||||||
|
|
||||||
// Compile with GCC/GAS
|
// Compile with GCC/GAS
|
||||||
|
|
||||||
|
#if !defined(AS_MAX_PORTABILITY)
|
||||||
|
|
||||||
|
#if defined(__aarch64__)
|
||||||
|
|
||||||
.arch armv8-a
|
.arch armv8-a
|
||||||
.text
|
.text
|
||||||
|
|
||||||
|
@ -217,3 +221,7 @@ CallARM64RetInMemory:
|
||||||
.cfi_def_cfa_offset 0
|
.cfi_def_cfa_offset 0
|
||||||
ret
|
ret
|
||||||
.cfi_endproc
|
.cfi_endproc
|
||||||
|
|
||||||
|
#endif /* __aarch64__ */
|
||||||
|
|
||||||
|
#endif /* !AS_MAX_PORTABILITY */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
AngelCode Scripting Library
|
AngelCode Scripting Library
|
||||||
Copyright (c) 2003-2020 Andreas Jonsson
|
Copyright (c) 2003-2021 Andreas Jonsson
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any
|
warranty. In no event will the authors be held liable for any
|
||||||
|
@ -1513,7 +1513,8 @@ int asCCompiler::PrepareArgument(asCDataType *paramType, asCExprContext *ctx, as
|
||||||
else if( ctx->type.dataType.IsNullHandle() )
|
else if( ctx->type.dataType.IsNullHandle() )
|
||||||
{
|
{
|
||||||
// Make sure the argument type can support handles (or is itself a handle)
|
// Make sure the argument type can support handles (or is itself a handle)
|
||||||
if( !dt.SupportHandles() && !dt.IsObjectHandle() )
|
// Don't allow null handle to be converted to an object type of ASHANDLE here, that would require more logic to call the constructor (which should be handled in ImplicitConversion)
|
||||||
|
if( (!dt.SupportHandles() && !dt.IsObjectHandle()) || (dt.GetTypeInfo() && (dt.GetTypeInfo()->GetFlags() & asOBJ_ASHANDLE)) )
|
||||||
{
|
{
|
||||||
asCString str;
|
asCString str;
|
||||||
str.Format(TXT_CANT_IMPLICITLY_CONVERT_s_TO_s, ctx->type.dataType.Format(outFunc->nameSpace).AddressOf(), param.Format(outFunc->nameSpace).AddressOf());
|
str.Format(TXT_CANT_IMPLICITLY_CONVERT_s_TO_s, ctx->type.dataType.Format(outFunc->nameSpace).AddressOf(), param.Format(outFunc->nameSpace).AddressOf());
|
||||||
|
@ -2696,7 +2697,6 @@ bool asCCompiler::CompileAutoType(asCDataType &type, asCExprContext &compiledCtx
|
||||||
|
|
||||||
// For types that support handles auto should prefer handle
|
// For types that support handles auto should prefer handle
|
||||||
// as it is more efficient than making a copy
|
// as it is more efficient than making a copy
|
||||||
// TODO: 'auto a = ...;' and 'auto @a = ...;' works the same in this case. Is this what we want?
|
|
||||||
if( newType.SupportHandles() )
|
if( newType.SupportHandles() )
|
||||||
newType.MakeHandle(true);
|
newType.MakeHandle(true);
|
||||||
|
|
||||||
|
@ -3163,7 +3163,7 @@ bool asCCompiler::CompileInitialization(asCScriptNode *node, asCByteCode *bc, co
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Call the default constructur, then call the assignment operator
|
// Call the default constructor, then call the assignment operator
|
||||||
asCExprContext ctx(engine);
|
asCExprContext ctx(engine);
|
||||||
|
|
||||||
// Call the default constructor here
|
// Call the default constructor here
|
||||||
|
@ -3812,7 +3812,7 @@ int asCCompiler::CompileInitListElement(asSListPatternNode *&patternNode, asCScr
|
||||||
asCExprContext ctx(engine);
|
asCExprContext ctx(engine);
|
||||||
DoAssignment(&ctx, &lctx, &rctx, valueNode, valueNode, ttAssignment, valueNode);
|
DoAssignment(&ctx, &lctx, &rctx, valueNode, valueNode, ttAssignment, valueNode);
|
||||||
|
|
||||||
if( !lctx.type.dataType.IsPrimitive() )
|
if( !ctx.type.dataType.IsPrimitive() )
|
||||||
ctx.bc.Instr(asBC_PopPtr);
|
ctx.bc.Instr(asBC_PopPtr);
|
||||||
|
|
||||||
// Release temporary variables used by expression
|
// Release temporary variables used by expression
|
||||||
|
@ -3904,7 +3904,7 @@ int asCCompiler::CompileInitListElement(asSListPatternNode *&patternNode, asCScr
|
||||||
asCExprContext ctx(engine);
|
asCExprContext ctx(engine);
|
||||||
DoAssignment(&ctx, &lctx, &rctx, valueNode, valueNode, ttAssignment, valueNode);
|
DoAssignment(&ctx, &lctx, &rctx, valueNode, valueNode, ttAssignment, valueNode);
|
||||||
|
|
||||||
if( !lctx.type.dataType.IsPrimitive() )
|
if( !ctx.type.dataType.IsPrimitive() )
|
||||||
ctx.bc.Instr(asBC_PopPtr);
|
ctx.bc.Instr(asBC_PopPtr);
|
||||||
|
|
||||||
// Release temporary variables used by expression
|
// Release temporary variables used by expression
|
||||||
|
@ -4855,7 +4855,7 @@ void asCCompiler::PrepareTemporaryVariable(asCScriptNode *node, asCExprContext *
|
||||||
{
|
{
|
||||||
ctx->bc.Instr(asBC_PopPtr);
|
ctx->bc.Instr(asBC_PopPtr);
|
||||||
ctx->bc.InstrSHORT(asBC_PSF, ctx->type.stackOffset);
|
ctx->bc.InstrSHORT(asBC_PSF, ctx->type.stackOffset);
|
||||||
ctx->type.dataType.MakeReference(true);
|
ctx->type.dataType.MakeReference(IsVariableOnHeap(ctx->type.stackOffset));
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -5273,7 +5273,7 @@ int asCCompiler::AllocateVariable(const asCDataType &type, bool isTemporary, boo
|
||||||
|
|
||||||
bool isOnHeap = true;
|
bool isOnHeap = true;
|
||||||
if( t.IsPrimitive() ||
|
if( t.IsPrimitive() ||
|
||||||
(t.GetTypeInfo() && (t.GetTypeInfo()->GetFlags() & asOBJ_VALUE) && !forceOnHeap) )
|
(t.GetTypeInfo() && (t.GetTypeInfo()->GetFlags() & asOBJ_VALUE) && !forceOnHeap && !asReference) )
|
||||||
{
|
{
|
||||||
// Primitives and value types (unless overridden) are allocated on the stack
|
// Primitives and value types (unless overridden) are allocated on the stack
|
||||||
isOnHeap = false;
|
isOnHeap = false;
|
||||||
|
@ -6106,7 +6106,7 @@ asUINT asCCompiler::ImplicitConvPrimitiveToPrimitive(asCExprContext *ctx, const
|
||||||
// Start by implicitly converting constant values
|
// Start by implicitly converting constant values
|
||||||
if( ctx->type.isConstant )
|
if( ctx->type.isConstant )
|
||||||
{
|
{
|
||||||
ImplicitConversionConstant(ctx, to, node, convType);
|
ImplicitConversionConstant(ctx, to, generateCode ? node : 0, convType);
|
||||||
ctx->type.dataType.MakeReadOnly(to.IsReadOnly());
|
ctx->type.dataType.MakeReadOnly(to.IsReadOnly());
|
||||||
return cost;
|
return cost;
|
||||||
}
|
}
|
||||||
|
@ -6482,7 +6482,7 @@ asUINT asCCompiler::ImplicitConvLambdaToFunc(asCExprContext *ctx, const asCDataT
|
||||||
name.Format("$%s$%d", outFunc->GetDeclaration(), numLambdas++);
|
name.Format("$%s$%d", outFunc->GetDeclaration(), numLambdas++);
|
||||||
|
|
||||||
// Register the lambda with the builder for later compilation
|
// Register the lambda with the builder for later compilation
|
||||||
asCScriptFunction *func = builder->RegisterLambda(ctx->exprNode, script, funcDef, name, outFunc->nameSpace);
|
asCScriptFunction *func = builder->RegisterLambda(ctx->exprNode, script, funcDef, name, outFunc->nameSpace, outFunc->IsShared());
|
||||||
asASSERT( func == 0 || funcDef->IsSignatureExceptNameEqual(func) );
|
asASSERT( func == 0 || funcDef->IsSignatureExceptNameEqual(func) );
|
||||||
ctx->bc.InstrPTR(asBC_FuncPtr, func);
|
ctx->bc.InstrPTR(asBC_FuncPtr, func);
|
||||||
|
|
||||||
|
@ -7174,12 +7174,23 @@ asUINT asCCompiler::ImplicitConvObjectToObject(asCExprContext *ctx, const asCDat
|
||||||
asUINT cost = ImplicitConvObjectRef(ctx, to, node, convType, generateCode);
|
asUINT cost = ImplicitConvObjectRef(ctx, to, node, convType, generateCode);
|
||||||
|
|
||||||
// If the desired type is an asOBJ_ASHANDLE then we'll assume it is allowed to implicitly
|
// If the desired type is an asOBJ_ASHANDLE then we'll assume it is allowed to implicitly
|
||||||
// construct the object through any of the available constructors
|
// construct the object through any of the available constructors (except those marked as explicit)
|
||||||
if( to.GetTypeInfo() && (to.GetTypeInfo()->flags & asOBJ_ASHANDLE) && to.GetTypeInfo() != ctx->type.dataType.GetTypeInfo() && allowObjectConstruct )
|
if( to.GetTypeInfo() && (to.GetTypeInfo()->flags & asOBJ_ASHANDLE) && to.GetTypeInfo() != ctx->type.dataType.GetTypeInfo() && allowObjectConstruct )
|
||||||
{
|
{
|
||||||
asCArray<int> funcs;
|
asCArray<int> funcs;
|
||||||
funcs = CastToObjectType(to.GetTypeInfo())->beh.constructors;
|
funcs = CastToObjectType(to.GetTypeInfo())->beh.constructors;
|
||||||
|
|
||||||
|
// Don't allow use of explicit constructors/factories in implicit conversions
|
||||||
|
if (convType == asIC_IMPLICIT_CONV)
|
||||||
|
{
|
||||||
|
for (asUINT n = 0; n < funcs.GetLength(); n++)
|
||||||
|
{
|
||||||
|
asCScriptFunction* desc = builder->GetFunctionDescription(funcs[n]);
|
||||||
|
if (desc->IsExplicit())
|
||||||
|
funcs.RemoveIndex(n--);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
asCArray<asCExprContext *> args;
|
asCArray<asCExprContext *> args;
|
||||||
args.PushLast(ctx);
|
args.PushLast(ctx);
|
||||||
|
|
||||||
|
@ -8049,17 +8060,28 @@ void asCCompiler::ImplicitConversionConstant(asCExprContext *from, const asCData
|
||||||
// Verify if it is possible
|
// Verify if it is possible
|
||||||
if( to.GetSizeInMemoryBytes() == 1 )
|
if( to.GetSizeInMemoryBytes() == 1 )
|
||||||
{
|
{
|
||||||
if( asBYTE(from->type.GetConstantDW()) != from->type.GetConstantDW() )
|
if( (from->type.dataType.GetSizeInMemoryBytes() == 2 && asBYTE(from->type.GetConstantW()) != from->type.GetConstantW()) ||
|
||||||
|
(from->type.dataType.GetSizeInMemoryBytes() == 4 && asBYTE(from->type.GetConstantDW()) != from->type.GetConstantDW()) ||
|
||||||
|
(from->type.dataType.GetSizeInMemoryBytes() == 8 && asBYTE(from->type.GetConstantQW()) != from->type.GetConstantQW()) )
|
||||||
if( convType != asIC_EXPLICIT_VAL_CAST && node ) Warning(TXT_VALUE_TOO_LARGE_FOR_TYPE, node);
|
if( convType != asIC_EXPLICIT_VAL_CAST && node ) Warning(TXT_VALUE_TOO_LARGE_FOR_TYPE, node);
|
||||||
|
|
||||||
from->type.SetConstantB(asCDataType::CreatePrimitive(to.GetTokenType(), true), asBYTE(from->type.GetConstantDW()));
|
if( from->type.dataType.GetSizeInMemoryBytes() == 2 )
|
||||||
|
from->type.SetConstantB(asCDataType::CreatePrimitive(to.GetTokenType(), true), asBYTE(from->type.GetConstantW()));
|
||||||
|
else if (from->type.dataType.GetSizeInMemoryBytes() == 4)
|
||||||
|
from->type.SetConstantB(asCDataType::CreatePrimitive(to.GetTokenType(), true), asBYTE(from->type.GetConstantDW()));
|
||||||
|
else if (from->type.dataType.GetSizeInMemoryBytes() == 8)
|
||||||
|
from->type.SetConstantB(asCDataType::CreatePrimitive(to.GetTokenType(), true), asBYTE(from->type.GetConstantQW()));
|
||||||
}
|
}
|
||||||
else if( to.GetSizeInMemoryBytes() == 2 )
|
else if( to.GetSizeInMemoryBytes() == 2 )
|
||||||
{
|
{
|
||||||
if( asWORD(from->type.GetConstantDW()) != from->type.GetConstantDW())
|
if( (from->type.dataType.GetSizeInMemoryBytes() == 4 && asWORD(from->type.GetConstantDW()) != from->type.GetConstantDW()) ||
|
||||||
|
(from->type.dataType.GetSizeInMemoryBytes() == 8 && asWORD(from->type.GetConstantQW()) != from->type.GetConstantQW()) )
|
||||||
if( convType != asIC_EXPLICIT_VAL_CAST && node ) Warning(TXT_VALUE_TOO_LARGE_FOR_TYPE, node);
|
if( convType != asIC_EXPLICIT_VAL_CAST && node ) Warning(TXT_VALUE_TOO_LARGE_FOR_TYPE, node);
|
||||||
|
|
||||||
from->type.SetConstantW(asCDataType::CreatePrimitive(to.GetTokenType(), true), asWORD(from->type.GetConstantDW()));
|
if (from->type.dataType.GetSizeInMemoryBytes() == 4)
|
||||||
|
from->type.SetConstantW(asCDataType::CreatePrimitive(to.GetTokenType(), true), asWORD(from->type.GetConstantDW()));
|
||||||
|
else if (from->type.dataType.GetSizeInMemoryBytes() == 8)
|
||||||
|
from->type.SetConstantW(asCDataType::CreatePrimitive(to.GetTokenType(), true), asWORD(from->type.GetConstantQW()));
|
||||||
}
|
}
|
||||||
else if (to.GetSizeInMemoryBytes() == 4)
|
else if (to.GetSizeInMemoryBytes() == 4)
|
||||||
{
|
{
|
||||||
|
@ -8650,7 +8672,7 @@ int asCCompiler::CompileCondition(asCScriptNode *expr, asCExprContext *ctx)
|
||||||
{
|
{
|
||||||
Error(TXT_EXPR_MUST_BE_BOOL, cexpr);
|
Error(TXT_EXPR_MUST_BE_BOOL, cexpr);
|
||||||
e.type.SetConstantB(asCDataType::CreatePrimitive(ttBool, true), true);
|
e.type.SetConstantB(asCDataType::CreatePrimitive(ttBool, true), true);
|
||||||
}
|
}
|
||||||
ctype = e.type;
|
ctype = e.type;
|
||||||
|
|
||||||
if( ProcessPropertyGetAccessor(&e, cexpr) < 0)
|
if( ProcessPropertyGetAccessor(&e, cexpr) < 0)
|
||||||
|
@ -8673,44 +8695,22 @@ int asCCompiler::CompileCondition(asCScriptNode *expr, asCExprContext *ctx)
|
||||||
int rr = CompileAssignment(cexpr->next->next, &re);
|
int rr = CompileAssignment(cexpr->next->next, &re);
|
||||||
DetermineSingleFunc(&re, cexpr->next->next);
|
DetermineSingleFunc(&re, cexpr->next->next);
|
||||||
|
|
||||||
if( lr >= 0 && rr >= 0 )
|
if (lr >= 0 && rr >= 0)
|
||||||
{
|
{
|
||||||
// Don't allow any operators on expressions that take address of class method
|
// Don't allow any operators on expressions that take address of class method
|
||||||
if( le.IsClassMethod() || re.IsClassMethod() )
|
if (le.IsClassMethod() || re.IsClassMethod())
|
||||||
{
|
{
|
||||||
Error(TXT_INVALID_OP_ON_METHOD, expr);
|
Error(TXT_INVALID_OP_ON_METHOD, expr);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ProcessPropertyGetAccessor(&le, cexpr->next) < 0 )
|
if (ProcessPropertyGetAccessor(&le, cexpr->next) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if( ProcessPropertyGetAccessor(&re, cexpr->next->next) < 0 )
|
if (ProcessPropertyGetAccessor(&re, cexpr->next->next) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
bool isExplicitHandle = le.type.isExplicitHandle || re.type.isExplicitHandle;
|
bool isExplicitHandle = le.type.isExplicitHandle || re.type.isExplicitHandle;
|
||||||
|
|
||||||
// Allow a 0 or null in the first case to be implicitly converted to the second type
|
|
||||||
if( le.type.isConstant && le.type.GetConstantData() == 0 && le.type.dataType.IsIntegerType() )
|
|
||||||
{
|
|
||||||
asCDataType to = re.type.dataType;
|
|
||||||
to.MakeReference(false);
|
|
||||||
to.MakeReadOnly(true);
|
|
||||||
ImplicitConversionConstant(&le, to, cexpr->next, asIC_IMPLICIT_CONV);
|
|
||||||
}
|
|
||||||
else if( le.type.IsNullConstant() )
|
|
||||||
{
|
|
||||||
asCDataType to = re.type.dataType;
|
|
||||||
to.MakeHandle(true);
|
|
||||||
ImplicitConversion(&le, to, cexpr->next, asIC_IMPLICIT_CONV);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allow either case to be converted to const @ if the other is const @
|
|
||||||
if( (le.type.dataType.IsHandleToConst() && !le.type.IsNullConstant()) || (re.type.dataType.IsHandleToConst() && !re.type.dataType.IsNullHandle()) )
|
|
||||||
{
|
|
||||||
le.type.dataType.MakeHandleToConst(true);
|
|
||||||
re.type.dataType.MakeHandleToConst(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allow an anonymous initialization list to be converted to the type in the other condition
|
// Allow an anonymous initialization list to be converted to the type in the other condition
|
||||||
if (le.IsAnonymousInitList() && re.type.dataType.GetBehaviour() && re.type.dataType.GetBehaviour()->listFactory)
|
if (le.IsAnonymousInitList() && re.type.dataType.GetBehaviour() && re.type.dataType.GetBehaviour()->listFactory)
|
||||||
{
|
{
|
||||||
|
@ -8727,7 +8727,7 @@ int asCCompiler::CompileCondition(asCScriptNode *expr, asCExprContext *ctx)
|
||||||
ImplicitConversion(&re, to, cexpr->next->next, asIC_IMPLICIT_CONV);
|
ImplicitConversion(&re, to, cexpr->next->next, asIC_IMPLICIT_CONV);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (le.IsAnonymousInitList() )
|
if (le.IsAnonymousInitList())
|
||||||
{
|
{
|
||||||
Error(TXT_CANNOT_RESOLVE_AUTO, cexpr->next);
|
Error(TXT_CANNOT_RESOLVE_AUTO, cexpr->next);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -8738,6 +8738,81 @@ int asCCompiler::CompileCondition(asCScriptNode *expr, asCExprContext *ctx)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try to perform an implicit cast to make the two operands of the same type
|
||||||
|
// Choose the conversion that is the least costly
|
||||||
|
if (le.type.dataType != re.type.dataType)
|
||||||
|
{
|
||||||
|
asCExprContext tmp(engine);
|
||||||
|
tmp.type = le.type;
|
||||||
|
tmp.type.dataType.MakeReference(false);
|
||||||
|
asUINT costAtoB = ImplicitConversion(&tmp, re.type.dataType, cexpr->next, asIC_IMPLICIT_CONV, false);
|
||||||
|
if (!tmp.type.dataType.IsEqualExceptRef(re.type.dataType))
|
||||||
|
costAtoB = 0xFFFFFFFF;
|
||||||
|
tmp.type = re.type;
|
||||||
|
tmp.type.dataType.MakeReference(false);
|
||||||
|
asUINT costBtoA = ImplicitConversion(&tmp, le.type.dataType, cexpr->next->next, asIC_IMPLICIT_CONV, false);
|
||||||
|
if (!tmp.type.dataType.IsEqualExceptRef(le.type.dataType))
|
||||||
|
costBtoA = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
if (costAtoB < costBtoA && costAtoB != 0xFFFFFFFF)
|
||||||
|
{
|
||||||
|
Dereference(&le, true);
|
||||||
|
ImplicitConversion(&le, re.type.dataType, cexpr->next, asIC_IMPLICIT_CONV, true);
|
||||||
|
}
|
||||||
|
else if (costAtoB > costBtoA && costBtoA != 0xFFFFFFFF)
|
||||||
|
{
|
||||||
|
Dereference(&re, true);
|
||||||
|
ImplicitConversion(&re, le.type.dataType, cexpr->next->next, asIC_IMPLICIT_CONV, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the cost for conversion is the same in both directions we have an ambigious situation,
|
||||||
|
// which we do not resolve. In that case the script need to perform an explicit conversion
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow a 0 to be implicitly converted to the other type
|
||||||
|
if (le.type.isConstant && le.type.GetConstantData() == 0 && le.type.dataType.IsIntegerType())
|
||||||
|
{
|
||||||
|
asCDataType to = re.type.dataType;
|
||||||
|
to.MakeReference(false);
|
||||||
|
to.MakeReadOnly(true);
|
||||||
|
ImplicitConversionConstant(&le, to, cexpr->next, asIC_IMPLICIT_CONV);
|
||||||
|
}
|
||||||
|
else if( re.type.isConstant && re.type.GetConstantData() == 0 && re.type.dataType.IsIntegerType())
|
||||||
|
{
|
||||||
|
asCDataType to = le.type.dataType;
|
||||||
|
to.MakeReference(false);
|
||||||
|
to.MakeReadOnly(true);
|
||||||
|
ImplicitConversionConstant(&re, to, cexpr->next->next, asIC_IMPLICIT_CONV);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow expression to be converted to handle if the other is handle
|
||||||
|
if (!le.type.dataType.IsObjectHandle() && re.type.dataType.IsObjectHandle() && le.type.dataType.GetTypeInfo() == re.type.dataType.GetTypeInfo() )
|
||||||
|
{
|
||||||
|
asCDataType dt = le.type.dataType;
|
||||||
|
dt.MakeHandle(true);
|
||||||
|
ImplicitConversion(&le, dt, cexpr->next, asIC_IMPLICIT_CONV);
|
||||||
|
}
|
||||||
|
if (!re.type.dataType.IsObjectHandle() && le.type.dataType.IsObjectHandle() && le.type.dataType.GetTypeInfo() == re.type.dataType.GetTypeInfo())
|
||||||
|
{
|
||||||
|
asCDataType dt = re.type.dataType;
|
||||||
|
dt.MakeHandle(true);
|
||||||
|
ImplicitConversion(&re, dt, cexpr->next->next, asIC_IMPLICIT_CONV);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow either case to be converted to const @ if the other is const @
|
||||||
|
if( (le.type.dataType.IsHandleToConst() && !le.type.IsNullConstant()) || (re.type.dataType.IsHandleToConst() && !re.type.dataType.IsNullHandle()) )
|
||||||
|
{
|
||||||
|
le.type.dataType.MakeHandleToConst(true);
|
||||||
|
re.type.dataType.MakeHandleToConst(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure both expressions have the same type
|
||||||
|
if (!le.type.dataType.IsEqualExceptRefAndConst(re.type.dataType))
|
||||||
|
{
|
||||||
|
Error(TXT_BOTH_MUST_BE_SAME, expr);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------
|
//---------------------------------
|
||||||
// Output the byte code
|
// Output the byte code
|
||||||
int afterLabel = nextLabel++;
|
int afterLabel = nextLabel++;
|
||||||
|
@ -8766,10 +8841,6 @@ int asCCompiler::CompileCondition(asCScriptNode *expr, asCExprContext *ctx)
|
||||||
MergeExprBytecode(ctx, &re);
|
MergeExprBytecode(ctx, &re);
|
||||||
ctx->bc.Label((short)afterLabel);
|
ctx->bc.Label((short)afterLabel);
|
||||||
|
|
||||||
// Make sure both expressions have the same type
|
|
||||||
if( le.type.dataType != re.type.dataType )
|
|
||||||
Error(TXT_BOTH_MUST_BE_SAME, expr);
|
|
||||||
|
|
||||||
// Set the type of the result
|
// Set the type of the result
|
||||||
ctx->type = le.type;
|
ctx->type = le.type;
|
||||||
}
|
}
|
||||||
|
@ -8810,7 +8881,7 @@ int asCCompiler::CompileCondition(asCScriptNode *expr, asCExprContext *ctx)
|
||||||
// with a stack offset (i.e. it will not be allowed to use asBC_VAR)
|
// with a stack offset (i.e. it will not be allowed to use asBC_VAR)
|
||||||
|
|
||||||
if( le.type.isLValue && re.type.isLValue &&
|
if( le.type.isLValue && re.type.isLValue &&
|
||||||
le.deferredParams.GetLength() == 0 && re.deferredParams.GetLength() ==0 &&
|
le.deferredParams.GetLength() == 0 && re.deferredParams.GetLength() == 0 &&
|
||||||
!le.type.isTemporary && !re.type.isTemporary &&
|
!le.type.isTemporary && !re.type.isTemporary &&
|
||||||
le.type.dataType == re.type.dataType )
|
le.type.dataType == re.type.dataType )
|
||||||
{
|
{
|
||||||
|
@ -8928,6 +8999,9 @@ int asCCompiler::CompileCondition(asCScriptNode *expr, asCExprContext *ctx)
|
||||||
// Release the old temporary variable
|
// Release the old temporary variable
|
||||||
ReleaseTemporaryVariable(le.type, &ctx->bc);
|
ReleaseTemporaryVariable(le.type, &ctx->bc);
|
||||||
|
|
||||||
|
// Process any deferred arguments in the expressions as these must not survive until after the condition returns
|
||||||
|
ProcessDeferredParams(ctx);
|
||||||
|
|
||||||
ctx->bc.InstrINT(asBC_JMP, afterLabel);
|
ctx->bc.InstrINT(asBC_JMP, afterLabel);
|
||||||
|
|
||||||
// Start of the right expression
|
// Start of the right expression
|
||||||
|
@ -8950,11 +9024,10 @@ int asCCompiler::CompileCondition(asCScriptNode *expr, asCExprContext *ctx)
|
||||||
// Release the old temporary variable
|
// Release the old temporary variable
|
||||||
ReleaseTemporaryVariable(re.type, &ctx->bc);
|
ReleaseTemporaryVariable(re.type, &ctx->bc);
|
||||||
|
|
||||||
ctx->bc.Label((short)afterLabel);
|
// Process any deferred arguments in the expressions as these must not survive until after the condition returns
|
||||||
|
ProcessDeferredParams(ctx);
|
||||||
|
|
||||||
// Make sure both expressions have the same type
|
ctx->bc.Label((short)afterLabel);
|
||||||
if( !le.type.dataType.IsEqualExceptConst(re.type.dataType) )
|
|
||||||
Error(TXT_BOTH_MUST_BE_SAME, expr);
|
|
||||||
|
|
||||||
// Set the temporary variable as output
|
// Set the temporary variable as output
|
||||||
ctx->type = rtemp;
|
ctx->type = rtemp;
|
||||||
|
@ -9366,7 +9439,7 @@ asCCompiler::SYMBOLTYPE asCCompiler::SymbolLookup(const asCString &name, const a
|
||||||
// TODO: child funcdef: A scope can include a template type, e.g. array<ns::type>
|
// TODO: child funcdef: A scope can include a template type, e.g. array<ns::type>
|
||||||
int n = currScope.FindLast("::");
|
int n = currScope.FindLast("::");
|
||||||
asCString typeName = n >= 0 ? currScope.SubString(n + 2) : currScope;
|
asCString typeName = n >= 0 ? currScope.SubString(n + 2) : currScope;
|
||||||
asCString nsName = n >= 0 ? currScope.SubString(0, n) : "";
|
asCString nsName = n >= 0 ? currScope.SubString(0, n) : asCString("");
|
||||||
|
|
||||||
// If the scope represents a type that the current class inherits
|
// If the scope represents a type that the current class inherits
|
||||||
// from then that should be used instead of going through the namespaces
|
// from then that should be used instead of going through the namespaces
|
||||||
|
@ -10988,7 +11061,8 @@ int asCCompiler::CompileConstructCall(asCScriptNode *node, asCExprContext *ctx)
|
||||||
if( conv.type.dataType.IsEqualExceptRef(dt) && cost > 0 )
|
if( conv.type.dataType.IsEqualExceptRef(dt) && cost > 0 )
|
||||||
{
|
{
|
||||||
// Make sure the result is a reference, just as if to a local variable
|
// Make sure the result is a reference, just as if to a local variable
|
||||||
dt.MakeReference(true);
|
if( !dt.IsFuncdef() )
|
||||||
|
dt.MakeReference(true);
|
||||||
|
|
||||||
// Make sure any property accessor is already evaluated
|
// Make sure any property accessor is already evaluated
|
||||||
if( ProcessPropertyGetAccessor(args[0], args[0]->exprNode) < 0 )
|
if( ProcessPropertyGetAccessor(args[0], args[0]->exprNode) < 0 )
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
AngelCode Scripting Library
|
AngelCode Scripting Library
|
||||||
Copyright (c) 2003-2020 Andreas Jonsson
|
Copyright (c) 2003-2021 Andreas Jonsson
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any
|
warranty. In no event will the authors be held liable for any
|
||||||
|
@ -252,26 +252,27 @@
|
||||||
// compiler is the same for both, when this is so these flags are used to produce the
|
// compiler is the same for both, when this is so these flags are used to produce the
|
||||||
// right code.
|
// right code.
|
||||||
|
|
||||||
// AS_WIN - Microsoft Windows
|
// AS_WIN - Microsoft Windows
|
||||||
// AS_LINUX - Linux
|
// AS_LINUX - Linux
|
||||||
// AS_MAC - Apple Macintosh
|
// AS_MAC - Apple Macintosh
|
||||||
// AS_BSD - BSD based OS (FreeBSD, DragonFly, OpenBSD, etc)
|
// AS_BSD - BSD based OS (FreeBSD, DragonFly, OpenBSD, etc)
|
||||||
// AS_XBOX - Microsoft XBox
|
// AS_XBOX - Microsoft XBox
|
||||||
// AS_XBOX360 - Microsoft XBox 360
|
// AS_XBOX360 - Microsoft XBox 360
|
||||||
// AS_PSP - Sony Playstation Portable
|
// AS_PSP - Sony Playstation Portable
|
||||||
// AS_PSVITA - Sony Playstation Vita
|
// AS_PSVITA - Sony Playstation Vita
|
||||||
// AS_PS2 - Sony Playstation 2
|
// AS_PS2 - Sony Playstation 2
|
||||||
// AS_PS3 - Sony Playstation 3
|
// AS_PS3 - Sony Playstation 3
|
||||||
// AS_DC - Sega Dreamcast
|
// AS_DC - Sega Dreamcast
|
||||||
// AS_GC - Nintendo GameCube
|
// AS_GC - Nintendo GameCube
|
||||||
// AS_WII - Nintendo Wii
|
// AS_WII - Nintendo Wii
|
||||||
// AS_WIIU - Nintendo Wii U
|
// AS_WIIU - Nintendo Wii U
|
||||||
// AS_IPHONE - Apple IPhone
|
// AS_NINTENDOSWITCH - Nintendo Switch
|
||||||
// AS_ANDROID - Android
|
// AS_IPHONE - Apple IPhone
|
||||||
// AS_HAIKU - Haiku
|
// AS_ANDROID - Android
|
||||||
// AS_ILLUMOS - Illumos like (OpenSolaris, OpenIndiana, NCP, etc)
|
// AS_HAIKU - Haiku
|
||||||
// AS_MARMALADE - Marmalade cross platform SDK (a layer on top of the OS)
|
// AS_ILLUMOS - Illumos like (OpenSolaris, OpenIndiana, NCP, etc)
|
||||||
// AS_SUN - Sun UNIX
|
// AS_MARMALADE - Marmalade cross platform SDK (a layer on top of the OS)
|
||||||
|
// AS_SUN - Sun UNIX
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -656,6 +657,37 @@
|
||||||
// Native calling conventions are not yet supported
|
// Native calling conventions are not yet supported
|
||||||
#define AS_MAX_PORTABILITY
|
#define AS_MAX_PORTABILITY
|
||||||
|
|
||||||
|
// Nintendo Switch
|
||||||
|
// Note, __SWITCH__ is not an official define in the Nintendo dev kit.
|
||||||
|
// You need to manually add this to the project when compiling for Switch.
|
||||||
|
#elif defined(__SWITCH__)
|
||||||
|
#define AS_NINTENDOSWITCH
|
||||||
|
|
||||||
|
#if (!defined(__LP64__))
|
||||||
|
#error write me
|
||||||
|
#else
|
||||||
|
#define AS_ARM64
|
||||||
|
#undef STDCALL
|
||||||
|
#define STDCALL
|
||||||
|
|
||||||
|
#undef GNU_STYLE_VIRTUAL_METHOD
|
||||||
|
#undef AS_NO_THISCALL_FUNCTOR_METHOD
|
||||||
|
|
||||||
|
#define HAS_128_BIT_PRIMITIVES
|
||||||
|
|
||||||
|
#define CDECL_RETURN_SIMPLE_IN_MEMORY
|
||||||
|
#define STDCALL_RETURN_SIMPLE_IN_MEMORY
|
||||||
|
#define THISCALL_RETURN_SIMPLE_IN_MEMORY
|
||||||
|
|
||||||
|
#undef THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
|
||||||
|
#undef CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
|
||||||
|
#undef STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
|
||||||
|
|
||||||
|
#define THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 5
|
||||||
|
#define CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 5
|
||||||
|
#define STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 5
|
||||||
|
#endif
|
||||||
|
|
||||||
// Marmalade is a cross platform SDK. It uses g++ to compile for iOS and Android
|
// Marmalade is a cross platform SDK. It uses g++ to compile for iOS and Android
|
||||||
#elif defined(__S3E__)
|
#elif defined(__S3E__)
|
||||||
#ifndef AS_MARMALADE
|
#ifndef AS_MARMALADE
|
||||||
|
@ -757,7 +789,7 @@
|
||||||
#undef STDCALL
|
#undef STDCALL
|
||||||
#define STDCALL
|
#define STDCALL
|
||||||
|
|
||||||
#elif (defined(__arm64__))
|
#elif (defined(__aarch64__))
|
||||||
// The IPhone 5S+ uses an ARM64 processor
|
// The IPhone 5S+ uses an ARM64 processor
|
||||||
|
|
||||||
// AngelScript currently doesn't support native calling
|
// AngelScript currently doesn't support native calling
|
||||||
|
@ -779,7 +811,7 @@
|
||||||
#undef COMPLEX_RETURN_MASK
|
#undef COMPLEX_RETURN_MASK
|
||||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
|
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
|
||||||
|
|
||||||
#elif defined(__LP64__) && !defined(__ppc__) && !defined(__PPC__) && !defined(__arm64__)
|
#elif defined(__LP64__) && !defined(__ppc__) && !defined(__PPC__) && !defined(__aarch64__)
|
||||||
// http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/LowLevelABI/140-x86-64_Function_Calling_Conventions/x86_64.html#//apple_ref/doc/uid/TP40005035-SW1
|
// http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/LowLevelABI/140-x86-64_Function_Calling_Conventions/x86_64.html#//apple_ref/doc/uid/TP40005035-SW1
|
||||||
#define AS_X64_GCC
|
#define AS_X64_GCC
|
||||||
#undef AS_NO_THISCALL_FUNCTOR_METHOD
|
#undef AS_NO_THISCALL_FUNCTOR_METHOD
|
||||||
|
@ -1091,30 +1123,40 @@
|
||||||
#undef COMPLEX_RETURN_MASK
|
#undef COMPLEX_RETURN_MASK
|
||||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
|
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
|
||||||
|
|
||||||
#if (defined(_ARM_) || defined(__arm__))
|
#if (defined(_ARM_) || defined(__arm__) || defined(__aarch64__) || defined(__AARCH64EL__))
|
||||||
// Android ARM
|
// Android ARM
|
||||||
|
|
||||||
// TODO: The stack unwind on exceptions currently fails due to the assembler code in as_callfunc_arm_gcc.S
|
|
||||||
#define AS_NO_EXCEPTIONS
|
|
||||||
|
|
||||||
#undef THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
|
#undef THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
|
||||||
#undef CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
|
#undef CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
|
||||||
#undef STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
|
#undef STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
|
||||||
|
|
||||||
#define THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
|
|
||||||
#define CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
|
|
||||||
#define STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
|
|
||||||
|
|
||||||
// The stdcall calling convention is not used on the arm cpu
|
// The stdcall calling convention is not used on the arm cpu
|
||||||
#undef STDCALL
|
#undef STDCALL
|
||||||
#define STDCALL
|
#define STDCALL
|
||||||
|
|
||||||
#undef GNU_STYLE_VIRTUAL_METHOD
|
#undef GNU_STYLE_VIRTUAL_METHOD
|
||||||
|
|
||||||
#define AS_ARM
|
|
||||||
#undef AS_NO_THISCALL_FUNCTOR_METHOD
|
#undef AS_NO_THISCALL_FUNCTOR_METHOD
|
||||||
#define AS_SOFTFP
|
|
||||||
#define AS_CALLEE_DESTROY_OBJ_BY_VAL
|
#if (!defined(__LP64__))
|
||||||
|
// TODO: The stack unwind on exceptions currently fails due to the assembler code in as_callfunc_arm_gcc.S
|
||||||
|
#define AS_NO_EXCEPTIONS
|
||||||
|
|
||||||
|
#define THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
|
||||||
|
#define CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
|
||||||
|
#define STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
|
||||||
|
|
||||||
|
#define AS_ARM
|
||||||
|
#define AS_SOFTFP
|
||||||
|
#define AS_CALLEE_DESTROY_OBJ_BY_VAL
|
||||||
|
#elif (defined(__LP64__) || defined(__aarch64__))
|
||||||
|
#define AS_ARM64
|
||||||
|
|
||||||
|
#define HAS_128_BIT_PRIMITIVES
|
||||||
|
|
||||||
|
#define THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 5
|
||||||
|
#define CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 5
|
||||||
|
#define STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 5
|
||||||
|
#endif
|
||||||
#elif (defined(i386) || defined(__i386) || defined(__i386__)) && !defined(__LP64__)
|
#elif (defined(i386) || defined(__i386) || defined(__i386__)) && !defined(__LP64__)
|
||||||
// Android Intel x86 (same config as Linux x86). Tested with Intel x86 Atom System Image.
|
// Android Intel x86 (same config as Linux x86). Tested with Intel x86 Atom System Image.
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
AngelCode Scripting Library
|
AngelCode Scripting Library
|
||||||
Copyright (c) 2003-2020 Andreas Jonsson
|
Copyright (c) 2003-2021 Andreas Jonsson
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any
|
warranty. In no event will the authors be held liable for any
|
||||||
|
@ -2882,7 +2882,8 @@ void asCContext::ExecuteNext()
|
||||||
m_regs.stackPointer = l_sp;
|
m_regs.stackPointer = l_sp;
|
||||||
m_regs.stackFramePointer = l_fp;
|
m_regs.stackFramePointer = l_fp;
|
||||||
|
|
||||||
if( !(objType->flags & asOBJ_NOCOUNT) )
|
// Update ref counter for object types that require it
|
||||||
|
if( !(objType->flags & (asOBJ_NOCOUNT | asOBJ_VALUE)) )
|
||||||
{
|
{
|
||||||
// Release previous object held by destination pointer
|
// Release previous object held by destination pointer
|
||||||
if( *d != 0 && beh->release )
|
if( *d != 0 && beh->release )
|
||||||
|
@ -3912,21 +3913,21 @@ void asCContext::ExecuteNext()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( func->funcType == asFUNC_SCRIPT )
|
if (func->funcType == asFUNC_SCRIPT)
|
||||||
{
|
{
|
||||||
m_regs.programPointer++;
|
m_regs.programPointer++;
|
||||||
CallScriptFunction(func);
|
CallScriptFunction(func);
|
||||||
}
|
}
|
||||||
else if( func->funcType == asFUNC_DELEGATE )
|
else if (func->funcType == asFUNC_DELEGATE)
|
||||||
{
|
{
|
||||||
// Push the object pointer on the stack. There is always a reserved space for this so
|
// Push the object pointer on the stack. There is always a reserved space for this so
|
||||||
// we don't don't need to worry about overflowing the allocated memory buffer
|
// we don't don't need to worry about overflowing the allocated memory buffer
|
||||||
asASSERT( m_regs.stackPointer - AS_PTR_SIZE >= m_stackBlocks[m_stackIndex] );
|
asASSERT(m_regs.stackPointer - AS_PTR_SIZE >= m_stackBlocks[m_stackIndex]);
|
||||||
m_regs.stackPointer -= AS_PTR_SIZE;
|
m_regs.stackPointer -= AS_PTR_SIZE;
|
||||||
*(asPWORD*)m_regs.stackPointer = asPWORD(func->objForDelegate);
|
*(asPWORD*)m_regs.stackPointer = asPWORD(func->objForDelegate);
|
||||||
|
|
||||||
// Call the delegated method
|
// Call the delegated method
|
||||||
if( func->funcForDelegate->funcType == asFUNC_SYSTEM )
|
if (func->funcForDelegate->funcType == asFUNC_SYSTEM)
|
||||||
{
|
{
|
||||||
m_regs.stackPointer += CallSystemFunction(func->funcForDelegate->id, this);
|
m_regs.stackPointer += CallSystemFunction(func->funcForDelegate->id, this);
|
||||||
|
|
||||||
|
@ -3942,16 +3943,33 @@ void asCContext::ExecuteNext()
|
||||||
CallInterfaceMethod(func->funcForDelegate);
|
CallInterfaceMethod(func->funcForDelegate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (func->funcType == asFUNC_SYSTEM)
|
||||||
{
|
{
|
||||||
asASSERT( func->funcType == asFUNC_SYSTEM );
|
|
||||||
|
|
||||||
m_regs.stackPointer += CallSystemFunction(func->id, this);
|
m_regs.stackPointer += CallSystemFunction(func->id, this);
|
||||||
|
|
||||||
// Update program position after the call so the line number
|
// Update program position after the call so the line number
|
||||||
// is correct in case the system function queries it
|
// is correct in case the system function queries it
|
||||||
m_regs.programPointer++;
|
m_regs.programPointer++;
|
||||||
}
|
}
|
||||||
|
else if (func->funcType == asFUNC_IMPORTED)
|
||||||
|
{
|
||||||
|
m_regs.programPointer++;
|
||||||
|
int funcId = m_engine->importedFunctions[func->id & ~FUNC_IMPORTED]->boundFunctionId;
|
||||||
|
if (funcId > 0)
|
||||||
|
CallScriptFunction(m_engine->scriptFunctions[funcId]);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Tell the exception handler to clean up the arguments to this method
|
||||||
|
m_needToCleanupArgs = true;
|
||||||
|
|
||||||
|
SetInternalException(TXT_UNBOUND_FUNCTION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Should not get here
|
||||||
|
asASSERT(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract the values from the context again
|
// Extract the values from the context again
|
||||||
|
@ -4141,7 +4159,8 @@ void asCContext::ExecuteNext()
|
||||||
m_regs.stackPointer = l_sp;
|
m_regs.stackPointer = l_sp;
|
||||||
m_regs.stackFramePointer = l_fp;
|
m_regs.stackFramePointer = l_fp;
|
||||||
|
|
||||||
if( !(objType->flags & asOBJ_NOCOUNT) )
|
// Update ref counter for object types that require it
|
||||||
|
if( !(objType->flags & (asOBJ_NOCOUNT | asOBJ_VALUE)) )
|
||||||
{
|
{
|
||||||
// Release previous object held by destination pointer
|
// Release previous object held by destination pointer
|
||||||
if( *d != 0 && beh->release )
|
if( *d != 0 && beh->release )
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
AngelCode Scripting Library
|
AngelCode Scripting Library
|
||||||
Copyright (c) 2003-2020 Andreas Jonsson
|
Copyright (c) 2003-2021 Andreas Jonsson
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any
|
warranty. In no event will the authors be held liable for any
|
||||||
|
@ -1470,7 +1470,8 @@ const char *asCModule::GetImportedFunctionDeclaration(asUINT index) const
|
||||||
if( func == 0 ) return 0;
|
if( func == 0 ) return 0;
|
||||||
|
|
||||||
asCString *tempString = &asCThreadManager::GetLocalData()->string;
|
asCString *tempString = &asCThreadManager::GetLocalData()->string;
|
||||||
*tempString = func->GetDeclarationStr();
|
// TODO: Allow the application to decide if the parameter name should be included or not (requires change in the interface)
|
||||||
|
*tempString = func->GetDeclarationStr(true, true, false);
|
||||||
|
|
||||||
return tempString->AddressOf();
|
return tempString->AddressOf();
|
||||||
}
|
}
|
||||||
|
@ -1536,28 +1537,28 @@ int asCModule::UnbindAllImportedFunctions()
|
||||||
void asCModule::AddClassType(asCObjectType* type)
|
void asCModule::AddClassType(asCObjectType* type)
|
||||||
{
|
{
|
||||||
m_classTypes.PushLast(type);
|
m_classTypes.PushLast(type);
|
||||||
m_typeLookup.Insert({type->nameSpace, type->name}, type);
|
m_typeLookup.Insert(asSNameSpaceNamePair(type->nameSpace, type->name), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
// internal
|
// internal
|
||||||
void asCModule::AddEnumType(asCEnumType* type)
|
void asCModule::AddEnumType(asCEnumType* type)
|
||||||
{
|
{
|
||||||
m_enumTypes.PushLast(type);
|
m_enumTypes.PushLast(type);
|
||||||
m_typeLookup.Insert({type->nameSpace, type->name}, type);
|
m_typeLookup.Insert(asSNameSpaceNamePair(type->nameSpace, type->name), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
// internal
|
// internal
|
||||||
void asCModule::AddTypeDef(asCTypedefType* type)
|
void asCModule::AddTypeDef(asCTypedefType* type)
|
||||||
{
|
{
|
||||||
m_typeDefs.PushLast(type);
|
m_typeDefs.PushLast(type);
|
||||||
m_typeLookup.Insert({type->nameSpace, type->name}, type);
|
m_typeLookup.Insert(asSNameSpaceNamePair(type->nameSpace, type->name), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
// internal
|
// internal
|
||||||
void asCModule::AddFuncDef(asCFuncdefType* type)
|
void asCModule::AddFuncDef(asCFuncdefType* type)
|
||||||
{
|
{
|
||||||
m_funcDefs.PushLast(type);
|
m_funcDefs.PushLast(type);
|
||||||
m_typeLookup.Insert({type->nameSpace, type->name}, type);
|
m_typeLookup.Insert(asSNameSpaceNamePair(type->nameSpace, type->name), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
// internal
|
// internal
|
||||||
|
@ -1569,8 +1570,8 @@ void asCModule::ReplaceFuncDef(asCFuncdefType* type, asCFuncdefType* newType)
|
||||||
m_funcDefs[i] = newType;
|
m_funcDefs[i] = newType;
|
||||||
|
|
||||||
// Replace it in the lookup map too
|
// Replace it in the lookup map too
|
||||||
asSMapNode<asSNameSpaceNamePair, asCTypeInfo*>* result = nullptr;
|
asSMapNode<asSNameSpaceNamePair, asCTypeInfo*>* result = 0;
|
||||||
if(m_typeLookup.MoveTo(&result, {type->nameSpace, type->name}))
|
if(m_typeLookup.MoveTo(&result, asSNameSpaceNamePair(type->nameSpace, type->name)))
|
||||||
{
|
{
|
||||||
asASSERT( result->value == type );
|
asASSERT( result->value == type );
|
||||||
result->value = newType;
|
result->value = newType;
|
||||||
|
@ -1581,8 +1582,8 @@ void asCModule::ReplaceFuncDef(asCFuncdefType* type, asCFuncdefType* newType)
|
||||||
// internal
|
// internal
|
||||||
asCTypeInfo *asCModule::GetType(const asCString &type, asSNameSpace *ns) const
|
asCTypeInfo *asCModule::GetType(const asCString &type, asSNameSpace *ns) const
|
||||||
{
|
{
|
||||||
asSMapNode<asSNameSpaceNamePair, asCTypeInfo*>* result = nullptr;
|
asSMapNode<asSNameSpaceNamePair, asCTypeInfo*>* result = 0;
|
||||||
if(m_typeLookup.MoveTo(&result, {ns, type}))
|
if(m_typeLookup.MoveTo(&result, asSNameSpaceNamePair(ns, type)))
|
||||||
{
|
{
|
||||||
return result->value;
|
return result->value;
|
||||||
}
|
}
|
||||||
|
@ -1592,8 +1593,8 @@ asCTypeInfo *asCModule::GetType(const asCString &type, asSNameSpace *ns) const
|
||||||
// internal
|
// internal
|
||||||
asCObjectType *asCModule::GetObjectType(const char *type, asSNameSpace *ns) const
|
asCObjectType *asCModule::GetObjectType(const char *type, asSNameSpace *ns) const
|
||||||
{
|
{
|
||||||
asSMapNode<asSNameSpaceNamePair, asCTypeInfo*>* result = nullptr;
|
asSMapNode<asSNameSpaceNamePair, asCTypeInfo*>* result = 0;
|
||||||
if(m_typeLookup.MoveTo(&result, {ns, type}))
|
if(m_typeLookup.MoveTo(&result, asSNameSpaceNamePair(ns, type)))
|
||||||
{
|
{
|
||||||
return CastToObjectType(result->value);
|
return CastToObjectType(result->value);
|
||||||
}
|
}
|
||||||
|
@ -1759,11 +1760,11 @@ int asCModule::CompileGlobalVar(const char *sectionName, const char *code, int l
|
||||||
}
|
}
|
||||||
|
|
||||||
// interface
|
// interface
|
||||||
int asCModule::CompileFunction(const char *sectionName, const char *code, int lineOffset, asDWORD compileFlags, asIScriptFunction **outFunc)
|
int asCModule::CompileFunction(const char* sectionName, const char* code, int lineOffset, asDWORD compileFlags, asIScriptFunction** outFunc)
|
||||||
{
|
{
|
||||||
// Make sure the outFunc is null if the function fails, so the
|
// Make sure the outFunc is null if the function fails, so the
|
||||||
// application doesn't attempt to release a non-existent function
|
// application doesn't attempt to release a non-existent function
|
||||||
if( outFunc )
|
if (outFunc)
|
||||||
*outFunc = 0;
|
*outFunc = 0;
|
||||||
|
|
||||||
#ifdef AS_NO_COMPILER
|
#ifdef AS_NO_COMPILER
|
||||||
|
@ -1774,19 +1775,19 @@ int asCModule::CompileFunction(const char *sectionName, const char *code, int li
|
||||||
return asNOT_SUPPORTED;
|
return asNOT_SUPPORTED;
|
||||||
#else
|
#else
|
||||||
// Validate arguments
|
// Validate arguments
|
||||||
if( code == 0 ||
|
if (code == 0 ||
|
||||||
(compileFlags != 0 && compileFlags != asCOMP_ADD_TO_MODULE) )
|
(compileFlags != 0 && compileFlags != asCOMP_ADD_TO_MODULE))
|
||||||
return asINVALID_ARG;
|
return asINVALID_ARG;
|
||||||
|
|
||||||
// Only one thread may build at one time
|
// Only one thread may build at one time
|
||||||
// TODO: It should be possible to have multiple threads perform compilations
|
// TODO: It should be possible to have multiple threads perform compilations
|
||||||
int r = m_engine->RequestBuild();
|
int r = m_engine->RequestBuild();
|
||||||
if( r < 0 )
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
// Prepare the engine
|
// Prepare the engine
|
||||||
m_engine->PrepareEngine();
|
m_engine->PrepareEngine();
|
||||||
if( m_engine->configFailed )
|
if (m_engine->configFailed)
|
||||||
{
|
{
|
||||||
m_engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, TXT_INVALID_CONFIGURATION);
|
m_engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, TXT_INVALID_CONFIGURATION);
|
||||||
m_engine->BuildCompleted();
|
m_engine->BuildCompleted();
|
||||||
|
@ -1796,9 +1797,19 @@ int asCModule::CompileFunction(const char *sectionName, const char *code, int li
|
||||||
// Compile the single function
|
// Compile the single function
|
||||||
asCBuilder funcBuilder(m_engine, this);
|
asCBuilder funcBuilder(m_engine, this);
|
||||||
asCString str = code;
|
asCString str = code;
|
||||||
asCScriptFunction *func = 0;
|
asCScriptFunction* func = 0;
|
||||||
r = funcBuilder.CompileFunction(sectionName, str.AddressOf(), lineOffset, compileFlags, &func);
|
r = funcBuilder.CompileFunction(sectionName, str.AddressOf(), lineOffset, compileFlags, &func);
|
||||||
|
|
||||||
|
if (r >= 0)
|
||||||
|
{
|
||||||
|
// Invoke the JIT compiler if it has been set
|
||||||
|
asIJITCompiler* jit = m_engine->GetJITCompiler();
|
||||||
|
if (jit)
|
||||||
|
{
|
||||||
|
func->JITCompile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_engine->BuildCompleted();
|
m_engine->BuildCompleted();
|
||||||
|
|
||||||
if( r >= 0 && outFunc && func )
|
if( r >= 0 && outFunc && func )
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
AngelCode Scripting Library
|
AngelCode Scripting Library
|
||||||
Copyright (c) 2003-2019 Andreas Jonsson
|
Copyright (c) 2003-2021 Andreas Jonsson
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any
|
warranty. In no event will the authors be held liable for any
|
||||||
|
@ -2488,7 +2488,7 @@ asCScriptNode *asCParser::ParseScript(bool inBlock)
|
||||||
UNREACHABLE_RETURN;
|
UNREACHABLE_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
// BNF:1: NAMESPACE ::= 'namespace' IDENTIFIER '{' SCRIPT '}'
|
// BNF:1: NAMESPACE ::= 'namespace' IDENTIFIER {'::' IDENTIFIER} '{' SCRIPT '}'
|
||||||
asCScriptNode *asCParser::ParseNamespace()
|
asCScriptNode *asCParser::ParseNamespace()
|
||||||
{
|
{
|
||||||
asCScriptNode *node = CreateNode(snNamespace);
|
asCScriptNode *node = CreateNode(snNamespace);
|
||||||
|
@ -2505,11 +2505,32 @@ asCScriptNode *asCParser::ParseNamespace()
|
||||||
Error(InsteadFound(t1), &t1);
|
Error(InsteadFound(t1), &t1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: namespace: Allow declaration of multiple nested namespace with namespace A::B::C { }
|
|
||||||
node->AddChildLast(ParseIdentifier());
|
node->AddChildLast(ParseIdentifier());
|
||||||
if( isSyntaxError ) return node;
|
if( isSyntaxError ) return node;
|
||||||
|
|
||||||
|
asCScriptNode *lowestNode = node;
|
||||||
GetToken(&t1);
|
GetToken(&t1);
|
||||||
|
while (t1.type == ttScope)
|
||||||
|
{
|
||||||
|
lowestNode->UpdateSourcePos(t1.pos, t1.length);
|
||||||
|
|
||||||
|
asCScriptNode *scopeNode = CreateNode(snScript);
|
||||||
|
if (scopeNode == 0)
|
||||||
|
return 0;
|
||||||
|
lowestNode->AddChildLast(scopeNode);
|
||||||
|
|
||||||
|
lowestNode = CreateNode(snNamespace);
|
||||||
|
if (lowestNode == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
scopeNode->AddChildLast(lowestNode);
|
||||||
|
lowestNode->AddChildLast(ParseIdentifier());
|
||||||
|
if (isSyntaxError)
|
||||||
|
return node;
|
||||||
|
|
||||||
|
GetToken(&t1);
|
||||||
|
}
|
||||||
|
|
||||||
if( t1.type == ttStartStatementBlock )
|
if( t1.type == ttStartStatementBlock )
|
||||||
node->UpdateSourcePos(t1.pos, t1.length);
|
node->UpdateSourcePos(t1.pos, t1.length);
|
||||||
else
|
else
|
||||||
|
@ -2521,7 +2542,7 @@ asCScriptNode *asCParser::ParseNamespace()
|
||||||
|
|
||||||
sToken start = t1;
|
sToken start = t1;
|
||||||
|
|
||||||
node->AddChildLast(ParseScript(true));
|
lowestNode->AddChildLast(ParseScript(true));
|
||||||
|
|
||||||
if( !isSyntaxError )
|
if( !isSyntaxError )
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
AngelCode Scripting Library
|
AngelCode Scripting Library
|
||||||
Copyright (c) 2003-2020 Andreas Jonsson
|
Copyright (c) 2003-2021 Andreas Jonsson
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any
|
warranty. In no event will the authors be held liable for any
|
||||||
|
@ -155,7 +155,7 @@ int asCReader::ReadInner()
|
||||||
noDebugInfo = ReadEncodedUInt() ? VALUE_OF_BOOLEAN_TRUE : 0;
|
noDebugInfo = ReadEncodedUInt() ? VALUE_OF_BOOLEAN_TRUE : 0;
|
||||||
|
|
||||||
// Read enums
|
// Read enums
|
||||||
count = ReadEncodedUInt();
|
count = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
module->m_enumTypes.Allocate(count, false);
|
module->m_enumTypes.Allocate(count, false);
|
||||||
for( i = 0; i < count && !error; i++ )
|
for( i = 0; i < count && !error; i++ )
|
||||||
{
|
{
|
||||||
|
@ -228,7 +228,7 @@ int asCReader::ReadInner()
|
||||||
|
|
||||||
// classTypes[]
|
// classTypes[]
|
||||||
// First restore the structure names, then the properties
|
// First restore the structure names, then the properties
|
||||||
count = ReadEncodedUInt();
|
count = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
module->m_classTypes.Allocate(count, false);
|
module->m_classTypes.Allocate(count, false);
|
||||||
for( i = 0; i < count && !error; ++i )
|
for( i = 0; i < count && !error; ++i )
|
||||||
{
|
{
|
||||||
|
@ -299,7 +299,7 @@ int asCReader::ReadInner()
|
||||||
if( error ) return asERROR;
|
if( error ) return asERROR;
|
||||||
|
|
||||||
// Read func defs
|
// Read func defs
|
||||||
count = ReadEncodedUInt();
|
count = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
module->m_funcDefs.Allocate(count, false);
|
module->m_funcDefs.Allocate(count, false);
|
||||||
for( i = 0; i < count && !error; i++ )
|
for( i = 0; i < count && !error; i++ )
|
||||||
{
|
{
|
||||||
|
@ -401,7 +401,7 @@ int asCReader::ReadInner()
|
||||||
if( error ) return asERROR;
|
if( error ) return asERROR;
|
||||||
|
|
||||||
// Read typedefs
|
// Read typedefs
|
||||||
count = ReadEncodedUInt();
|
count = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
module->m_typeDefs.Allocate(count, false);
|
module->m_typeDefs.Allocate(count, false);
|
||||||
for( i = 0; i < count && !error; i++ )
|
for( i = 0; i < count && !error; i++ )
|
||||||
{
|
{
|
||||||
|
@ -422,7 +422,7 @@ int asCReader::ReadInner()
|
||||||
if( error ) return asERROR;
|
if( error ) return asERROR;
|
||||||
|
|
||||||
// scriptGlobals[]
|
// scriptGlobals[]
|
||||||
count = ReadEncodedUInt();
|
count = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
if( count && engine->ep.disallowGlobalVars )
|
if( count && engine->ep.disallowGlobalVars )
|
||||||
{
|
{
|
||||||
engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, TXT_GLOBAL_VARS_NOT_ALLOWED);
|
engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, TXT_GLOBAL_VARS_NOT_ALLOWED);
|
||||||
|
@ -435,7 +435,7 @@ int asCReader::ReadInner()
|
||||||
}
|
}
|
||||||
|
|
||||||
// scriptFunctions[]
|
// scriptFunctions[]
|
||||||
count = ReadEncodedUInt();
|
count = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
for( i = 0; i < count && !error; ++i )
|
for( i = 0; i < count && !error; ++i )
|
||||||
{
|
{
|
||||||
size_t len = module->m_scriptFunctions.GetLength();
|
size_t len = module->m_scriptFunctions.GetLength();
|
||||||
|
@ -496,7 +496,7 @@ int asCReader::ReadInner()
|
||||||
}
|
}
|
||||||
|
|
||||||
// globalFunctions[]
|
// globalFunctions[]
|
||||||
count = ReadEncodedUInt();
|
count = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
for( i = 0; i < count && !error; ++i )
|
for( i = 0; i < count && !error; ++i )
|
||||||
{
|
{
|
||||||
bool isNew;
|
bool isNew;
|
||||||
|
@ -516,7 +516,7 @@ int asCReader::ReadInner()
|
||||||
if( error ) return asERROR;
|
if( error ) return asERROR;
|
||||||
|
|
||||||
// bindInformations[]
|
// bindInformations[]
|
||||||
count = ReadEncodedUInt();
|
count = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
module->m_bindInformations.Allocate(count, false);
|
module->m_bindInformations.Allocate(count, false);
|
||||||
for( i = 0; i < count && !error; ++i )
|
for( i = 0; i < count && !error; ++i )
|
||||||
{
|
{
|
||||||
|
@ -554,7 +554,7 @@ int asCReader::ReadInner()
|
||||||
if( error ) return asERROR;
|
if( error ) return asERROR;
|
||||||
|
|
||||||
// usedTypes[]
|
// usedTypes[]
|
||||||
count = ReadEncodedUInt();
|
count = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
usedTypes.Allocate(count, false);
|
usedTypes.Allocate(count, false);
|
||||||
for( i = 0; i < count && !error; ++i )
|
for( i = 0; i < count && !error; ++i )
|
||||||
{
|
{
|
||||||
|
@ -660,7 +660,7 @@ void asCReader::ReadUsedStringConstants()
|
||||||
asCString str;
|
asCString str;
|
||||||
|
|
||||||
asUINT count;
|
asUINT count;
|
||||||
count = ReadEncodedUInt();
|
count = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
|
|
||||||
if (count > 0 && engine->stringFactory == 0)
|
if (count > 0 && engine->stringFactory == 0)
|
||||||
{
|
{
|
||||||
|
@ -681,7 +681,7 @@ void asCReader::ReadUsedFunctions()
|
||||||
TimeIt("asCReader::ReadUsedFunctions");
|
TimeIt("asCReader::ReadUsedFunctions");
|
||||||
|
|
||||||
asUINT count;
|
asUINT count;
|
||||||
count = ReadEncodedUInt();
|
count = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
usedFunctions.SetLength(count);
|
usedFunctions.SetLength(count);
|
||||||
if( usedFunctions.GetLength() != count )
|
if( usedFunctions.GetLength() != count )
|
||||||
{
|
{
|
||||||
|
@ -1026,13 +1026,7 @@ void asCReader::ReadFunctionSignature(asCScriptFunction *func, asCObjectType **p
|
||||||
|
|
||||||
ReadDataType(&func->returnType);
|
ReadDataType(&func->returnType);
|
||||||
|
|
||||||
count = ReadEncodedUInt();
|
count = SanityCheck(ReadEncodedUInt(), 256);
|
||||||
if( count > 256 )
|
|
||||||
{
|
|
||||||
// Too many arguments, must be something wrong in the file
|
|
||||||
Error(TXT_INVALID_BYTECODE_d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
func->parameterTypes.Allocate(count, false);
|
func->parameterTypes.Allocate(count, false);
|
||||||
for( i = 0; i < count; ++i )
|
for( i = 0; i < count; ++i )
|
||||||
{
|
{
|
||||||
|
@ -1253,12 +1247,12 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
|
||||||
|
|
||||||
ReadByteCode(func);
|
ReadByteCode(func);
|
||||||
|
|
||||||
func->scriptData->variableSpace = ReadEncodedUInt();
|
func->scriptData->variableSpace = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
|
|
||||||
func->scriptData->objVariablesOnHeap = 0;
|
func->scriptData->objVariablesOnHeap = 0;
|
||||||
if (bits & 8)
|
if (bits & 8)
|
||||||
{
|
{
|
||||||
count = ReadEncodedUInt();
|
count = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
func->scriptData->objVariablePos.Allocate(count, false);
|
func->scriptData->objVariablePos.Allocate(count, false);
|
||||||
func->scriptData->objVariableTypes.Allocate(count, false);
|
func->scriptData->objVariableTypes.Allocate(count, false);
|
||||||
for (i = 0; i < count; ++i)
|
for (i = 0; i < count; ++i)
|
||||||
|
@ -1275,14 +1269,14 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (count > 0)
|
if (count > 0)
|
||||||
func->scriptData->objVariablesOnHeap = ReadEncodedUInt();
|
func->scriptData->objVariablesOnHeap = SanityCheck(ReadEncodedUInt(), 10000);
|
||||||
|
|
||||||
int length = ReadEncodedUInt();
|
int length = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
func->scriptData->objVariableInfo.SetLength(length);
|
func->scriptData->objVariableInfo.SetLength(length);
|
||||||
for (i = 0; i < length; ++i)
|
for (i = 0; i < length; ++i)
|
||||||
{
|
{
|
||||||
func->scriptData->objVariableInfo[i].programPos = ReadEncodedUInt();
|
func->scriptData->objVariableInfo[i].programPos = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
func->scriptData->objVariableInfo[i].variableOffset = ReadEncodedUInt();
|
func->scriptData->objVariableInfo[i].variableOffset = SanityCheck(ReadEncodedInt(), 10000);
|
||||||
asEObjVarInfoOption option = (asEObjVarInfoOption)ReadEncodedUInt();
|
asEObjVarInfoOption option = (asEObjVarInfoOption)ReadEncodedUInt();
|
||||||
func->scriptData->objVariableInfo[i].option = option;
|
func->scriptData->objVariableInfo[i].option = option;
|
||||||
if (option != asOBJ_INIT &&
|
if (option != asOBJ_INIT &&
|
||||||
|
@ -1301,19 +1295,19 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
|
||||||
if (bits & 16)
|
if (bits & 16)
|
||||||
{
|
{
|
||||||
// Read info on try/catch blocks
|
// Read info on try/catch blocks
|
||||||
int length = ReadEncodedUInt();
|
int length = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
func->scriptData->tryCatchInfo.SetLength(length);
|
func->scriptData->tryCatchInfo.SetLength(length);
|
||||||
for (i = 0; i < length; ++i)
|
for (i = 0; i < length; ++i)
|
||||||
{
|
{
|
||||||
// The program position must be adjusted to be in number of instructions
|
// The program position must be adjusted to be in number of instructions
|
||||||
func->scriptData->tryCatchInfo[i].tryPos = ReadEncodedUInt();
|
func->scriptData->tryCatchInfo[i].tryPos = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
func->scriptData->tryCatchInfo[i].catchPos = ReadEncodedUInt();
|
func->scriptData->tryCatchInfo[i].catchPos = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!noDebugInfo)
|
if (!noDebugInfo)
|
||||||
{
|
{
|
||||||
int length = ReadEncodedUInt();
|
int length = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
func->scriptData->lineNumbers.SetLength(length);
|
func->scriptData->lineNumbers.SetLength(length);
|
||||||
if (int(func->scriptData->lineNumbers.GetLength()) != length)
|
if (int(func->scriptData->lineNumbers.GetLength()) != length)
|
||||||
{
|
{
|
||||||
|
@ -1326,7 +1320,7 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
|
||||||
func->scriptData->lineNumbers[i] = ReadEncodedUInt();
|
func->scriptData->lineNumbers[i] = ReadEncodedUInt();
|
||||||
|
|
||||||
// Read the array of script sections
|
// Read the array of script sections
|
||||||
length = ReadEncodedUInt();
|
length = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
func->scriptData->sectionIdxs.SetLength(length);
|
func->scriptData->sectionIdxs.SetLength(length);
|
||||||
if (int(func->scriptData->sectionIdxs.GetLength()) != length)
|
if (int(func->scriptData->sectionIdxs.GetLength()) != length)
|
||||||
{
|
{
|
||||||
|
@ -1351,7 +1345,7 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
|
||||||
// Read the variable information
|
// Read the variable information
|
||||||
if (!noDebugInfo)
|
if (!noDebugInfo)
|
||||||
{
|
{
|
||||||
int length = ReadEncodedUInt();
|
int length = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
func->scriptData->variables.Allocate(length, false);
|
func->scriptData->variables.Allocate(length, false);
|
||||||
for (i = 0; i < length; i++)
|
for (i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
|
@ -1366,7 +1360,7 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
|
||||||
func->scriptData->variables.PushLast(var);
|
func->scriptData->variables.PushLast(var);
|
||||||
|
|
||||||
var->declaredAtProgramPos = ReadEncodedUInt();
|
var->declaredAtProgramPos = ReadEncodedUInt();
|
||||||
var->stackOffset = ReadEncodedUInt();
|
var->stackOffset = SanityCheck(ReadEncodedInt(),10000);
|
||||||
ReadString(&var->name);
|
ReadString(&var->name);
|
||||||
ReadDataType(&var->type);
|
ReadDataType(&var->type);
|
||||||
|
|
||||||
|
@ -1551,7 +1545,7 @@ void asCReader::ReadTypeDeclaration(asCTypeInfo *type, int phase, bool *isExtern
|
||||||
// Read the initial attributes
|
// Read the initial attributes
|
||||||
ReadString(&type->name);
|
ReadString(&type->name);
|
||||||
ReadData(&type->flags, 4);
|
ReadData(&type->flags, 4);
|
||||||
type->size = ReadEncodedUInt();
|
type->size = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
asCString ns;
|
asCString ns;
|
||||||
ReadString(&ns);
|
ReadString(&ns);
|
||||||
type->nameSpace = engine->AddNameSpace(ns.AddressOf());
|
type->nameSpace = engine->AddNameSpace(ns.AddressOf());
|
||||||
|
@ -1613,7 +1607,7 @@ void asCReader::ReadTypeDeclaration(asCTypeInfo *type, int phase, bool *isExtern
|
||||||
if( type->flags & asOBJ_ENUM )
|
if( type->flags & asOBJ_ENUM )
|
||||||
{
|
{
|
||||||
asCEnumType *t = CastToEnumType(type);
|
asCEnumType *t = CastToEnumType(type);
|
||||||
int count = ReadEncodedUInt();
|
int count = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
bool sharedExists = existingShared.MoveTo(0, type);
|
bool sharedExists = existingShared.MoveTo(0, type);
|
||||||
if( !sharedExists )
|
if( !sharedExists )
|
||||||
{
|
{
|
||||||
|
@ -1695,7 +1689,7 @@ void asCReader::ReadTypeDeclaration(asCTypeInfo *type, int phase, bool *isExtern
|
||||||
}
|
}
|
||||||
|
|
||||||
// interfaces[] / interfaceVFTOffsets[]
|
// interfaces[] / interfaceVFTOffsets[]
|
||||||
int size = ReadEncodedUInt();
|
int size = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
if( sharedExists )
|
if( sharedExists )
|
||||||
{
|
{
|
||||||
for( int n = 0; n < size; n++ )
|
for( int n = 0; n < size; n++ )
|
||||||
|
@ -1725,7 +1719,7 @@ void asCReader::ReadTypeDeclaration(asCTypeInfo *type, int phase, bool *isExtern
|
||||||
|
|
||||||
if (!ot->IsInterface())
|
if (!ot->IsInterface())
|
||||||
{
|
{
|
||||||
asUINT offset = ReadEncodedUInt();
|
asUINT offset = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
ot->interfaceVFTOffsets.PushLast(offset);
|
ot->interfaceVFTOffsets.PushLast(offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1776,7 +1770,7 @@ void asCReader::ReadTypeDeclaration(asCTypeInfo *type, int phase, bool *isExtern
|
||||||
ot->beh.destruct = 0;
|
ot->beh.destruct = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size = ReadEncodedUInt();
|
size = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
for( int n = 0; n < size; n++ )
|
for( int n = 0; n < size; n++ )
|
||||||
{
|
{
|
||||||
func = ReadFunction(isNew, !sharedExists, !sharedExists, !sharedExists);
|
func = ReadFunction(isNew, !sharedExists, !sharedExists, !sharedExists);
|
||||||
|
@ -1880,7 +1874,7 @@ void asCReader::ReadTypeDeclaration(asCTypeInfo *type, int phase, bool *isExtern
|
||||||
}
|
}
|
||||||
|
|
||||||
// methods[]
|
// methods[]
|
||||||
size = ReadEncodedUInt();
|
size = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
int n;
|
int n;
|
||||||
for( n = 0; n < size; n++ )
|
for( n = 0; n < size; n++ )
|
||||||
{
|
{
|
||||||
|
@ -1946,7 +1940,7 @@ void asCReader::ReadTypeDeclaration(asCTypeInfo *type, int phase, bool *isExtern
|
||||||
}
|
}
|
||||||
|
|
||||||
// virtualFunctionTable[]
|
// virtualFunctionTable[]
|
||||||
size = ReadEncodedUInt();
|
size = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
for( n = 0; n < size; n++ )
|
for( n = 0; n < size; n++ )
|
||||||
{
|
{
|
||||||
bool isNew;
|
bool isNew;
|
||||||
|
@ -2011,7 +2005,7 @@ void asCReader::ReadTypeDeclaration(asCTypeInfo *type, int phase, bool *isExtern
|
||||||
asASSERT(ot);
|
asASSERT(ot);
|
||||||
|
|
||||||
// properties[]
|
// properties[]
|
||||||
asUINT size = ReadEncodedUInt();
|
asUINT size = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
for( asUINT n = 0; n < size; n++ )
|
for( asUINT n = 0; n < size; n++ )
|
||||||
ReadObjectProperty(ot);
|
ReadObjectProperty(ot);
|
||||||
}
|
}
|
||||||
|
@ -2039,10 +2033,15 @@ asUINT asCReader::ReadEncodedUInt()
|
||||||
return asUINT(qw & 0xFFFFFFFFu);
|
return asUINT(qw & 0xFFFFFFFFu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int asCReader::ReadEncodedInt()
|
||||||
|
{
|
||||||
|
return int(ReadEncodedUInt());
|
||||||
|
}
|
||||||
|
|
||||||
asQWORD asCReader::ReadEncodedUInt64()
|
asQWORD asCReader::ReadEncodedUInt64()
|
||||||
{
|
{
|
||||||
asQWORD i = 0;
|
asQWORD i = 0;
|
||||||
asBYTE b;
|
asBYTE b = 0xFF; // set to 0xFF to better catch if the stream doesn't update the value
|
||||||
ReadData(&b, 1);
|
ReadData(&b, 1);
|
||||||
bool isNegative = ( b & 0x80 ) ? true : false;
|
bool isNegative = ( b & 0x80 ) ? true : false;
|
||||||
b &= 0x7F;
|
b &= 0x7F;
|
||||||
|
@ -2113,9 +2112,35 @@ asQWORD asCReader::ReadEncodedUInt64()
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
asUINT asCReader::SanityCheck(asUINT val, asUINT max)
|
||||||
|
{
|
||||||
|
if (val > max)
|
||||||
|
{
|
||||||
|
Error(TXT_INVALID_BYTECODE_d);
|
||||||
|
|
||||||
|
// Return 0 as default value
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
int asCReader::SanityCheck(int val, asUINT max)
|
||||||
|
{
|
||||||
|
if (val > int(max) || val < -int(max))
|
||||||
|
{
|
||||||
|
Error(TXT_INVALID_BYTECODE_d);
|
||||||
|
|
||||||
|
// Return 0 as default value
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
void asCReader::ReadString(asCString* str)
|
void asCReader::ReadString(asCString* str)
|
||||||
{
|
{
|
||||||
asUINT len = ReadEncodedUInt();
|
asUINT len = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
if( len & 1 )
|
if( len & 1 )
|
||||||
{
|
{
|
||||||
asUINT idx = len/2;
|
asUINT idx = len/2;
|
||||||
|
@ -2261,7 +2286,7 @@ asCTypeInfo* asCReader::ReadTypeInfo()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
asUINT numSubTypes = ReadEncodedUInt();
|
asUINT numSubTypes = SanityCheck(ReadEncodedUInt(), 100);
|
||||||
asCArray<asCDataType> subTypes;
|
asCArray<asCDataType> subTypes;
|
||||||
for( asUINT n = 0; n < numSubTypes; n++ )
|
for( asUINT n = 0; n < numSubTypes; n++ )
|
||||||
{
|
{
|
||||||
|
@ -2422,7 +2447,7 @@ void asCReader::ReadByteCode(asCScriptFunction *func)
|
||||||
|
|
||||||
// Read number of instructions
|
// Read number of instructions
|
||||||
asUINT total, numInstructions;
|
asUINT total, numInstructions;
|
||||||
total = numInstructions = ReadEncodedUInt();
|
total = numInstructions = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
|
|
||||||
// Reserve some space for the instructions
|
// Reserve some space for the instructions
|
||||||
func->scriptData->byteCode.AllocateNoConstruct(numInstructions, false);
|
func->scriptData->byteCode.AllocateNoConstruct(numInstructions, false);
|
||||||
|
@ -2664,7 +2689,7 @@ void asCReader::ReadUsedTypeIds()
|
||||||
{
|
{
|
||||||
TimeIt("asCReader::ReadUsedTypeIds");
|
TimeIt("asCReader::ReadUsedTypeIds");
|
||||||
|
|
||||||
asUINT count = ReadEncodedUInt();
|
asUINT count = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
usedTypeIds.Allocate(count, false);
|
usedTypeIds.Allocate(count, false);
|
||||||
for( asUINT n = 0; n < count; n++ )
|
for( asUINT n = 0; n < count; n++ )
|
||||||
{
|
{
|
||||||
|
@ -2678,7 +2703,7 @@ void asCReader::ReadUsedGlobalProps()
|
||||||
{
|
{
|
||||||
TimeIt("asCReader::ReadUsedGlobalProps");
|
TimeIt("asCReader::ReadUsedGlobalProps");
|
||||||
|
|
||||||
int c = ReadEncodedUInt();
|
int c = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
|
|
||||||
usedGlobalProperties.Allocate(c, false);
|
usedGlobalProperties.Allocate(c, false);
|
||||||
|
|
||||||
|
@ -2719,7 +2744,7 @@ void asCReader::ReadUsedObjectProps()
|
||||||
{
|
{
|
||||||
TimeIt("asCReader::ReadUsedObjectProps");
|
TimeIt("asCReader::ReadUsedObjectProps");
|
||||||
|
|
||||||
asUINT c = ReadEncodedUInt();
|
asUINT c = SanityCheck(ReadEncodedUInt(), 1000000);
|
||||||
|
|
||||||
usedObjectProperties.SetLength(c);
|
usedObjectProperties.SetLength(c);
|
||||||
for( asUINT n = 0; n < c; n++ )
|
for( asUINT n = 0; n < c; n++ )
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
AngelCode Scripting Library
|
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
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any
|
warranty. In no event will the authors be held liable for any
|
||||||
|
@ -76,7 +76,10 @@ protected:
|
||||||
void ReadByteCode(asCScriptFunction *func);
|
void ReadByteCode(asCScriptFunction *func);
|
||||||
asWORD ReadEncodedUInt16();
|
asWORD ReadEncodedUInt16();
|
||||||
asUINT ReadEncodedUInt();
|
asUINT ReadEncodedUInt();
|
||||||
|
int ReadEncodedInt();
|
||||||
asQWORD ReadEncodedUInt64();
|
asQWORD ReadEncodedUInt64();
|
||||||
|
asUINT SanityCheck(asUINT val, asUINT max);
|
||||||
|
int SanityCheck(int val, asUINT max);
|
||||||
|
|
||||||
void ReadUsedTypeIds();
|
void ReadUsedTypeIds();
|
||||||
void ReadUsedFunctions();
|
void ReadUsedFunctions();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
AngelCode Scripting Library
|
AngelCode Scripting Library
|
||||||
Copyright (c) 2003-2020 Andreas Jonsson
|
Copyright (c) 2003-2021 Andreas Jonsson
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any
|
warranty. In no event will the authors be held liable for any
|
||||||
|
@ -951,12 +951,16 @@ asCModule *asCScriptEngine::FindNewOwnerForSharedFunc(asCScriptFunction *in_func
|
||||||
if( in_func->module != in_mod)
|
if( in_func->module != in_mod)
|
||||||
return in_func->module;
|
return in_func->module;
|
||||||
|
|
||||||
if (in_func->objectType && in_func->objectType->module &&
|
// Check if this is a class method or class factory for a type that has already been moved to a different module
|
||||||
in_func->objectType->module != in_func->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
|
// The object type for the method has already been transferred to
|
||||||
// another module, so transfer the method to the same module
|
// another module, so transfer the method to the same module
|
||||||
in_func->module = in_func->objectType->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
|
// Make sure the function is listed in the module
|
||||||
// The compiler may not have done this earlier, since the object
|
// The compiler may not have done this earlier, since the object
|
||||||
|
@ -1370,7 +1374,9 @@ int asCScriptEngine::GetFactoryIdByDecl(const asCObjectType *ot, const char *dec
|
||||||
for( asUINT n = 0; n < ot->beh.factories.GetLength(); n++ )
|
for( asUINT n = 0; n < ot->beh.factories.GetLength(); n++ )
|
||||||
{
|
{
|
||||||
asCScriptFunction *f = scriptFunctions[ot->beh.factories[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];
|
id = ot->beh.factories[n];
|
||||||
break;
|
break;
|
||||||
|
@ -2156,7 +2162,9 @@ int asCScriptEngine::RegisterBehaviourToObjectType(asCObjectType *objectType, as
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify the parameters
|
// 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 )
|
if( listPattern )
|
||||||
listPattern->Destroy(this);
|
listPattern->Destroy(this);
|
||||||
|
@ -4960,7 +4968,8 @@ int asCScriptEngine::RefCastObject(void *obj, asITypeInfo *fromType, asITypeInfo
|
||||||
|
|
||||||
// Look for ref cast behaviours
|
// Look for ref cast behaviours
|
||||||
asCScriptFunction *universalCastFunc = 0;
|
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++ )
|
for( asUINT n = 0; n < from->methods.GetLength(); n++ )
|
||||||
{
|
{
|
||||||
asCScriptFunction *func = scriptFunctions[from->methods[n]];
|
asCScriptFunction *func = scriptFunctions[from->methods[n]];
|
||||||
|
@ -5044,7 +5053,8 @@ void *asCScriptEngine::CreateScriptObject(const asITypeInfo *type)
|
||||||
{
|
{
|
||||||
if( type == 0 ) return 0;
|
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;
|
void *ptr = 0;
|
||||||
|
|
||||||
// Check that there is a default factory for ref types
|
// Check that there is a default factory for ref types
|
||||||
|
@ -5243,7 +5253,9 @@ void *asCScriptEngine::CreateUninitializedScriptObject(const asITypeInfo *type)
|
||||||
if( type == 0 || !(type->GetFlags() & asOBJ_SCRIPT_OBJECT) )
|
if( type == 0 || !(type->GetFlags() & asOBJ_SCRIPT_OBJECT) )
|
||||||
return 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;
|
||||||
|
|
||||||
// Construct the object, but do not call the actual constructor that initializes the members
|
// 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.
|
// The initialization will be done by the application afterwards, e.g. through serialization.
|
||||||
|
@ -5260,9 +5272,11 @@ void *asCScriptEngine::CreateScriptObjectCopy(void *origObj, const asITypeInfo *
|
||||||
{
|
{
|
||||||
if( origObj == 0 || type == 0 ) return 0;
|
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;
|
void *newObj = 0;
|
||||||
|
|
||||||
const asCObjectType *ot = reinterpret_cast<const asCObjectType*>(type);
|
|
||||||
if ((ot->flags & asOBJ_SCRIPT_OBJECT) && ot->beh.copyfactory)
|
if ((ot->flags & asOBJ_SCRIPT_OBJECT) && ot->beh.copyfactory)
|
||||||
{
|
{
|
||||||
// Call the script class' default factory with a context
|
// Call the script class' default factory with a context
|
||||||
|
@ -5286,7 +5300,7 @@ void *asCScriptEngine::CreateScriptObjectCopy(void *origObj, const asITypeInfo *
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if( ot->beh.copyconstruct )
|
else if(ot->beh.copyconstruct )
|
||||||
{
|
{
|
||||||
// Manually allocate the memory, then call the copy constructor
|
// Manually allocate the memory, then call the copy constructor
|
||||||
newObj = CallAlloc(ot);
|
newObj = CallAlloc(ot);
|
||||||
|
@ -5351,7 +5365,8 @@ int asCScriptEngine::AssignScriptObject(void *dstObj, void *srcObj, const asITyp
|
||||||
// TODO: Warn about invalid call in message stream (make it optional)
|
// TODO: Warn about invalid call in message stream (make it optional)
|
||||||
if( type == 0 || dstObj == 0 || srcObj == 0 ) return asINVALID_ARG;
|
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 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))
|
||||||
|
@ -5389,7 +5404,7 @@ void asCScriptEngine::AddRefScriptObject(void *obj, const asITypeInfo *type)
|
||||||
// Make sure it is not a null pointer
|
// Make sure it is not a null pointer
|
||||||
if( obj == 0 || type == 0 ) return;
|
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)
|
if (ti->flags & asOBJ_FUNCDEF)
|
||||||
{
|
{
|
||||||
CallObjectMethod(obj, functionBehaviours.beh.addref);
|
CallObjectMethod(obj, functionBehaviours.beh.addref);
|
||||||
|
@ -5411,7 +5426,7 @@ void asCScriptEngine::ReleaseScriptObject(void *obj, const asITypeInfo *type)
|
||||||
// Make sure it is not a null pointer
|
// Make sure it is not a null pointer
|
||||||
if( obj == 0 || type == 0 ) return;
|
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)
|
if (ti->flags & asOBJ_FUNCDEF)
|
||||||
{
|
{
|
||||||
CallObjectMethod(obj, functionBehaviours.beh.release);
|
CallObjectMethod(obj, functionBehaviours.beh.release);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
AngelCode Scripting Library
|
AngelCode Scripting Library
|
||||||
Copyright (c) 2003-2020 Andreas Jonsson
|
Copyright (c) 2003-2021 Andreas Jonsson
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any
|
warranty. In no event will the authors be held liable for any
|
||||||
|
@ -306,7 +306,9 @@ int asCScriptFunction::ParseListPattern(asSListPatternNode *&target, const char
|
||||||
asCBuilder builder(engine, 0);
|
asCBuilder builder(engine, 0);
|
||||||
asCScriptCode code;
|
asCScriptCode code;
|
||||||
code.SetCode("", decl, 0, false);
|
code.SetCode("", decl, 0, false);
|
||||||
dt = builder.CreateDataTypeFromNode(listNodes, &code, engine->defaultNamespace, false, CastToObjectType(returnType.GetTypeInfo()));
|
|
||||||
|
// For list factory we get the object type from the return type, for list constructor we get it from the object type directly
|
||||||
|
dt = builder.CreateDataTypeFromNode(listNodes, &code, engine->defaultNamespace, false, objectType ? objectType : CastToObjectType(returnType.GetTypeInfo()));
|
||||||
|
|
||||||
node->next = asNEW(asSListPatternDataTypeNode)(dt);
|
node->next = asNEW(asSListPatternDataTypeNode)(dt);
|
||||||
node = node->next;
|
node = node->next;
|
||||||
|
@ -1722,5 +1724,20 @@ bool asCScriptFunction::IsProperty() const
|
||||||
return traits.GetTrait(asTRAIT_PROPERTY);
|
return traits.GetTrait(asTRAIT_PROPERTY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// internal
|
||||||
|
bool asCScriptFunction::IsFactory() const
|
||||||
|
{
|
||||||
|
if (objectType) return false;
|
||||||
|
|
||||||
|
asCObjectType* type = CastToObjectType(returnType.GetTypeInfo());
|
||||||
|
if (type == 0) return false;
|
||||||
|
|
||||||
|
if (type->name != name) return false;
|
||||||
|
|
||||||
|
if (type->nameSpace != nameSpace) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
END_AS_NAMESPACE
|
END_AS_NAMESPACE
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
AngelCode Scripting Library
|
AngelCode Scripting Library
|
||||||
Copyright (c) 2003-2019 Andreas Jonsson
|
Copyright (c) 2003-2021 Andreas Jonsson
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any
|
warranty. In no event will the authors be held liable for any
|
||||||
|
@ -215,6 +215,7 @@ public:
|
||||||
void SetProtected(bool set) { traits.SetTrait(asTRAIT_PROTECTED, set); }
|
void SetProtected(bool set) { traits.SetTrait(asTRAIT_PROTECTED, set); }
|
||||||
void SetPrivate(bool set) { traits.SetTrait(asTRAIT_PRIVATE, set); }
|
void SetPrivate(bool set) { traits.SetTrait(asTRAIT_PRIVATE, set); }
|
||||||
void SetProperty(bool set) { traits.SetTrait(asTRAIT_PROPERTY, set); }
|
void SetProperty(bool set) { traits.SetTrait(asTRAIT_PROPERTY, set); }
|
||||||
|
bool IsFactory() const;
|
||||||
|
|
||||||
asCScriptFunction(asCScriptEngine *engine, asCModule *mod, asEFuncType funcType);
|
asCScriptFunction(asCScriptEngine *engine, asCModule *mod, asEFuncType funcType);
|
||||||
~asCScriptFunction();
|
~asCScriptFunction();
|
||||||
|
|
|
@ -336,6 +336,7 @@ asCScriptObject::asCScriptObject(asCObjectType *ot, bool doInitialize)
|
||||||
{
|
{
|
||||||
refCount.set(1);
|
refCount.set(1);
|
||||||
objType = ot;
|
objType = ot;
|
||||||
|
objType->AddRef();
|
||||||
isDestructCalled = false;
|
isDestructCalled = false;
|
||||||
extra = 0;
|
extra = 0;
|
||||||
hasRefCountReachedZero = false;
|
hasRefCountReachedZero = false;
|
||||||
|
@ -480,6 +481,7 @@ asCScriptObject::~asCScriptObject()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
objType->Release();
|
||||||
objType = 0;
|
objType = 0;
|
||||||
|
|
||||||
// Something is really wrong if the refCount is not 0 by now
|
// Something is really wrong if the refCount is not 0 by now
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
AngelCode Scripting Library
|
AngelCode Scripting Library
|
||||||
Copyright (c) 2012-2015 Andreas Jonsson
|
Copyright (c) 2012-2021 Andreas Jonsson
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any
|
warranty. In no event will the authors be held liable for any
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
AngelCode Scripting Library
|
AngelCode Scripting Library
|
||||||
Copyright (c) 2003-2019 Andreas Jonsson
|
Copyright (c) 2003-2021 Andreas Jonsson
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any
|
warranty. In no event will the authors be held liable for any
|
||||||
|
@ -48,7 +48,7 @@
|
||||||
#define TXT_ATTR_s_INFORMED_MULTIPLE_TIMES "Attribute '%s' informed multiple times"
|
#define TXT_ATTR_s_INFORMED_MULTIPLE_TIMES "Attribute '%s' informed multiple times"
|
||||||
#define TXT_AUTO_NOT_ALLOWED "Auto is not allowed here"
|
#define TXT_AUTO_NOT_ALLOWED "Auto is not allowed here"
|
||||||
|
|
||||||
#define TXT_BOTH_MUST_BE_SAME "Both expressions must have the same type"
|
#define TXT_BOTH_MUST_BE_SAME "Can't find unambiguous implicit conversion to make both expressions have the same type"
|
||||||
#define TXT_BOTH_CONDITIONS_MUST_CALL_CONSTRUCTOR "Both conditions must call constructor"
|
#define TXT_BOTH_CONDITIONS_MUST_CALL_CONSTRUCTOR "Both conditions must call constructor"
|
||||||
#define TEXT_BASE_DOESNT_HAVE_DEF_CONSTR "Base class doesn't have default constructor. Make explicit call to base constructor"
|
#define TEXT_BASE_DOESNT_HAVE_DEF_CONSTR "Base class doesn't have default constructor. Make explicit call to base constructor"
|
||||||
|
|
||||||
|
@ -189,6 +189,7 @@
|
||||||
#define TXT_NAME_CONFLICT_s_IS_MIXIN "Name conflict. '%s' is a mixin class."
|
#define TXT_NAME_CONFLICT_s_IS_MIXIN "Name conflict. '%s' is a mixin class."
|
||||||
#define TXT_NAME_CONFLICT_s_IS_VIRTPROP "Name conflict. '%s' is a virtual property."
|
#define TXT_NAME_CONFLICT_s_IS_VIRTPROP "Name conflict. '%s' is a virtual property."
|
||||||
#define TXT_NAME_CONFLICT_s_STRUCT "Name conflict. '%s' is a class."
|
#define TXT_NAME_CONFLICT_s_STRUCT "Name conflict. '%s' is a class."
|
||||||
|
#define TXT_NAME_CONFLICT_s_INTF "Name conflict. '%s' is an interface."
|
||||||
#define TXT_NAME_CONFLICT_s_OBJ_PROPERTY "Name conflict. '%s' is an object property."
|
#define TXT_NAME_CONFLICT_s_OBJ_PROPERTY "Name conflict. '%s' is an object property."
|
||||||
#define TXT_NAME_CONFLICT_s_METHOD "Name conflict. '%s' is a class method."
|
#define TXT_NAME_CONFLICT_s_METHOD "Name conflict. '%s' is a class method."
|
||||||
#define TXT_NAME_CONFLICT_s_ALREADY_USED "Name conflict. '%s' is already used."
|
#define TXT_NAME_CONFLICT_s_ALREADY_USED "Name conflict. '%s' is already used."
|
||||||
|
|
Loading…
Reference in New Issue