Update to angelscript 2.35
This commit is contained in:
parent
18e71dfe13
commit
fac54acbc9
|
@ -18,6 +18,6 @@
|
|||
"vscode-languageserver-textdocument": "^1.0.1"
|
||||
},
|
||||
"scripts": {
|
||||
"install": "cmake-js compile -d src -O build"
|
||||
"install": "cmake-js compile -d src -O build; tsc"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ cmake_policy(SET CMP0042 NEW)
|
|||
project(aslsp-native)
|
||||
|
||||
set (CMAKE_CXX_STANDARD 20)
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
|
||||
include_directories(${CMAKE_JS_INC} angelscript/include)
|
||||
message(info ${CMAKE_JS_INC})
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <assert.h>
|
||||
#include <stdio.h> // sprintf
|
||||
#include <string>
|
||||
#include <algorithm> // std::sort
|
||||
|
||||
#include "scriptarray.h"
|
||||
|
||||
|
@ -998,7 +999,7 @@ void CScriptArray::Destruct(SArrayBuffer *buf, asUINT start, asUINT end)
|
|||
|
||||
|
||||
// internal
|
||||
bool CScriptArray::Less(const void *a, const void *b, bool asc, asIScriptContext *ctx, SArrayCache *cache)
|
||||
bool CScriptArray::Less(const void *a, const void *b, bool asc)
|
||||
{
|
||||
if( !asc )
|
||||
{
|
||||
|
@ -1027,42 +1028,6 @@ bool CScriptArray::Less(const void *a, const void *b, bool asc, asIScriptContext
|
|||
#undef COMPARE
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
if( subTypeId & asTYPEID_OBJHANDLE )
|
||||
{
|
||||
// Allow sort to work even if the array contains null handles
|
||||
if( *(void**)a == 0 ) return true;
|
||||
if( *(void**)b == 0 ) return false;
|
||||
}
|
||||
|
||||
// Execute object opCmp
|
||||
if( cache && cache->cmpFunc )
|
||||
{
|
||||
// TODO: Add proper error handling
|
||||
r = ctx->Prepare(cache->cmpFunc); assert(r >= 0);
|
||||
|
||||
if( subTypeId & asTYPEID_OBJHANDLE )
|
||||
{
|
||||
r = ctx->SetObject(*((void**)a)); assert(r >= 0);
|
||||
r = ctx->SetArgObject(0, *((void**)b)); assert(r >= 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
r = ctx->SetObject((void*)a); assert(r >= 0);
|
||||
r = ctx->SetArgObject(0, (void*)b); assert(r >= 0);
|
||||
}
|
||||
|
||||
r = ctx->Execute();
|
||||
|
||||
if( r == asEXECUTION_FINISHED )
|
||||
{
|
||||
return (int)ctx->GetReturnDWord() < 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -1475,12 +1440,11 @@ void CScriptArray::Sort(asUINT startAt, asUINT count, bool asc)
|
|||
return;
|
||||
}
|
||||
|
||||
asBYTE tmp[16];
|
||||
asIScriptContext *cmpContext = 0;
|
||||
bool isNested = false;
|
||||
|
||||
if( subTypeId & ~asTYPEID_MASK_SEQNBR )
|
||||
{
|
||||
asIScriptContext *cmpContext = 0;
|
||||
bool isNested = false;
|
||||
|
||||
// Try to reuse the active context
|
||||
cmpContext = asGetActiveContext();
|
||||
if( cmpContext )
|
||||
|
@ -1491,38 +1455,83 @@ void CScriptArray::Sort(asUINT startAt, asUINT count, bool asc)
|
|||
cmpContext = 0;
|
||||
}
|
||||
if( cmpContext == 0 )
|
||||
{
|
||||
cmpContext = objType->GetEngine()->RequestContext();
|
||||
|
||||
// Do the sorting
|
||||
struct {
|
||||
bool asc;
|
||||
asIScriptContext *cmpContext;
|
||||
asIScriptFunction *cmpFunc;
|
||||
bool operator()(void *a, void *b) const
|
||||
{
|
||||
if( !asc )
|
||||
{
|
||||
// Swap items
|
||||
void *TEMP = a;
|
||||
a = b;
|
||||
b = TEMP;
|
||||
}
|
||||
|
||||
int r = 0;
|
||||
|
||||
// Allow sort to work even if the array contains null handles
|
||||
if( a == 0 ) return true;
|
||||
if( b == 0 ) return false;
|
||||
|
||||
// Execute object opCmp
|
||||
if( cmpFunc )
|
||||
{
|
||||
// TODO: Add proper error handling
|
||||
r = cmpContext->Prepare(cmpFunc); assert(r >= 0);
|
||||
r = cmpContext->SetObject(a); assert(r >= 0);
|
||||
r = cmpContext->SetArgObject(0, b); assert(r >= 0);
|
||||
r = cmpContext->Execute();
|
||||
|
||||
if( r == asEXECUTION_FINISHED )
|
||||
{
|
||||
return (int)cmpContext->GetReturnDWord() < 0;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
} customLess = {asc, cmpContext, cache ? cache->cmpFunc : 0};
|
||||
std::sort((void**)GetArrayItemPointer(start), (void**)GetArrayItemPointer(end), customLess);
|
||||
|
||||
// Clean up
|
||||
if( cmpContext )
|
||||
{
|
||||
if( isNested )
|
||||
{
|
||||
asEContextState state = cmpContext->GetState();
|
||||
cmpContext->PopState();
|
||||
if( state == asEXECUTION_ABORTED )
|
||||
cmpContext->Abort();
|
||||
}
|
||||
else
|
||||
objType->GetEngine()->ReturnContext(cmpContext);
|
||||
}
|
||||
}
|
||||
|
||||
// Insertion sort
|
||||
for( int i = start + 1; i < end; i++ )
|
||||
else
|
||||
{
|
||||
Copy(tmp, GetArrayItemPointer(i));
|
||||
|
||||
int j = i - 1;
|
||||
|
||||
while( j >= start && Less(GetDataPointer(tmp), At(j), asc, cmpContext, cache) )
|
||||
// TODO: Use std::sort for primitive types too
|
||||
|
||||
// Insertion sort
|
||||
asBYTE tmp[16];
|
||||
for( int i = start + 1; i < end; i++ )
|
||||
{
|
||||
Copy(GetArrayItemPointer(j + 1), GetArrayItemPointer(j));
|
||||
j--;
|
||||
}
|
||||
Copy(tmp, GetArrayItemPointer(i));
|
||||
|
||||
Copy(GetArrayItemPointer(j + 1), tmp);
|
||||
}
|
||||
int j = i - 1;
|
||||
|
||||
if( cmpContext )
|
||||
{
|
||||
if( isNested )
|
||||
{
|
||||
asEContextState state = cmpContext->GetState();
|
||||
cmpContext->PopState();
|
||||
if( state == asEXECUTION_ABORTED )
|
||||
cmpContext->Abort();
|
||||
while( j >= start && Less(GetDataPointer(tmp), At(j), asc) )
|
||||
{
|
||||
Copy(GetArrayItemPointer(j + 1), GetArrayItemPointer(j));
|
||||
j--;
|
||||
}
|
||||
|
||||
Copy(GetArrayItemPointer(j + 1), tmp);
|
||||
}
|
||||
else
|
||||
objType->GetEngine()->ReturnContext(cmpContext);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1550,7 +1559,6 @@ void CScriptArray::Sort(asIScriptFunction *func, asUINT startAt, asUINT count)
|
|||
return;
|
||||
}
|
||||
|
||||
asBYTE tmp[16];
|
||||
asIScriptContext *cmpContext = 0;
|
||||
bool isNested = false;
|
||||
|
||||
|
@ -1567,6 +1575,7 @@ void CScriptArray::Sort(asIScriptFunction *func, asUINT startAt, asUINT count)
|
|||
cmpContext = objType->GetEngine()->RequestContext();
|
||||
|
||||
// Insertion sort
|
||||
asBYTE tmp[16];
|
||||
for (asUINT i = start + 1; i < end; i++)
|
||||
{
|
||||
Copy(tmp, GetArrayItemPointer(i));
|
||||
|
|
|
@ -120,7 +120,7 @@ protected:
|
|||
CScriptArray(const CScriptArray &other);
|
||||
virtual ~CScriptArray();
|
||||
|
||||
bool Less(const void *a, const void *b, bool asc, asIScriptContext *ctx, SArrayCache *cache);
|
||||
bool Less(const void *a, const void *b, bool asc);
|
||||
void *GetArrayItemPointer(int index);
|
||||
void *GetDataPointer(void *buffer);
|
||||
void Copy(void *dst, void *src);
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
|
||||
// TODO: Implement flags for turning on/off include directives and conditional programming
|
||||
|
||||
|
||||
|
||||
//---------------------------
|
||||
// Declaration
|
||||
//
|
||||
|
@ -23,9 +25,10 @@
|
|||
#include <angelscript.h>
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1200
|
||||
// disable the annoying warnings on MSVC 6
|
||||
#pragma warning(disable : 4786)
|
||||
#pragma warning (disable:4786)
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
@ -197,7 +200,7 @@ protected:
|
|||
{
|
||||
bool operator()(const std::string &a, const std::string &b) const
|
||||
{
|
||||
return _strcmpi(a.c_str(), b.c_str()) < 0;
|
||||
return _stricmp(a.c_str(), b.c_str()) < 0;
|
||||
}
|
||||
};
|
||||
std::set<std::string, ci_less> includedScripts;
|
||||
|
|
|
@ -1,367 +1,360 @@
|
|||
#include "scripthandle.h"
|
||||
#include <assert.h>
|
||||
#include <new>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
static void Construct(CScriptHandle* self) { new (self) CScriptHandle(); }
|
||||
static void Construct(CScriptHandle* self, const CScriptHandle& o) { new (self) CScriptHandle(o); }
|
||||
static void Construct(CScriptHandle *self) { new(self) CScriptHandle(); }
|
||||
static void Construct(CScriptHandle *self, const CScriptHandle &o) { new(self) CScriptHandle(o); }
|
||||
// This one is not static because it needs to be friend with the CScriptHandle class
|
||||
void Construct(CScriptHandle* self, void* ref, int typeId) { new (self) CScriptHandle(ref, typeId); }
|
||||
static void Destruct(CScriptHandle* self) { self->~CScriptHandle(); }
|
||||
void Construct(CScriptHandle *self, void *ref, int typeId) { new(self) CScriptHandle(ref, typeId); }
|
||||
static void Destruct(CScriptHandle *self) { self->~CScriptHandle(); }
|
||||
|
||||
CScriptHandle::CScriptHandle() {
|
||||
m_ref = 0;
|
||||
m_type = 0;
|
||||
CScriptHandle::CScriptHandle()
|
||||
{
|
||||
m_ref = 0;
|
||||
m_type = 0;
|
||||
}
|
||||
|
||||
CScriptHandle::CScriptHandle(const CScriptHandle& other) {
|
||||
m_ref = other.m_ref;
|
||||
m_type = other.m_type;
|
||||
CScriptHandle::CScriptHandle(const CScriptHandle &other)
|
||||
{
|
||||
m_ref = other.m_ref;
|
||||
m_type = other.m_type;
|
||||
|
||||
AddRefHandle();
|
||||
AddRefHandle();
|
||||
}
|
||||
|
||||
CScriptHandle::CScriptHandle(void* ref, asITypeInfo* type) {
|
||||
m_ref = ref;
|
||||
m_type = type;
|
||||
CScriptHandle::CScriptHandle(void *ref, asITypeInfo *type)
|
||||
{
|
||||
m_ref = ref;
|
||||
m_type = type;
|
||||
|
||||
AddRefHandle();
|
||||
AddRefHandle();
|
||||
}
|
||||
|
||||
// This constructor shouldn't be called from the application
|
||||
// This constructor shouldn't be called from the application
|
||||
// directly as it requires an active script context
|
||||
CScriptHandle::CScriptHandle(void* ref, int typeId) {
|
||||
m_ref = 0;
|
||||
m_type = 0;
|
||||
CScriptHandle::CScriptHandle(void *ref, int typeId)
|
||||
{
|
||||
m_ref = 0;
|
||||
m_type = 0;
|
||||
|
||||
Assign(ref, typeId);
|
||||
Assign(ref, typeId);
|
||||
}
|
||||
|
||||
CScriptHandle::~CScriptHandle() { ReleaseHandle(); }
|
||||
|
||||
void CScriptHandle::ReleaseHandle() {
|
||||
if (m_ref && m_type) {
|
||||
asIScriptEngine* engine = m_type->GetEngine();
|
||||
engine->ReleaseScriptObject(m_ref, m_type);
|
||||
|
||||
engine->Release();
|
||||
|
||||
m_ref = 0;
|
||||
m_type = 0;
|
||||
}
|
||||
CScriptHandle::~CScriptHandle()
|
||||
{
|
||||
ReleaseHandle();
|
||||
}
|
||||
|
||||
void CScriptHandle::AddRefHandle() {
|
||||
if (m_ref && m_type) {
|
||||
asIScriptEngine* engine = m_type->GetEngine();
|
||||
engine->AddRefScriptObject(m_ref, m_type);
|
||||
void CScriptHandle::ReleaseHandle()
|
||||
{
|
||||
if( m_ref && m_type )
|
||||
{
|
||||
asIScriptEngine *engine = m_type->GetEngine();
|
||||
engine->ReleaseScriptObject(m_ref, m_type);
|
||||
|
||||
// Hold on to the engine so it isn't destroyed while
|
||||
// a reference to a script object is still held
|
||||
engine->AddRef();
|
||||
}
|
||||
engine->Release();
|
||||
|
||||
m_ref = 0;
|
||||
m_type = 0;
|
||||
}
|
||||
}
|
||||
|
||||
CScriptHandle& CScriptHandle::operator=(const CScriptHandle& other) {
|
||||
Set(other.m_ref, other.m_type);
|
||||
void CScriptHandle::AddRefHandle()
|
||||
{
|
||||
if( m_ref && m_type )
|
||||
{
|
||||
asIScriptEngine *engine = m_type->GetEngine();
|
||||
engine->AddRefScriptObject(m_ref, m_type);
|
||||
|
||||
return *this;
|
||||
// Hold on to the engine so it isn't destroyed while
|
||||
// a reference to a script object is still held
|
||||
engine->AddRef();
|
||||
}
|
||||
}
|
||||
|
||||
void CScriptHandle::Set(void* ref, asITypeInfo* type) {
|
||||
if (m_ref == ref)
|
||||
return;
|
||||
CScriptHandle &CScriptHandle::operator =(const CScriptHandle &other)
|
||||
{
|
||||
Set(other.m_ref, other.m_type);
|
||||
|
||||
ReleaseHandle();
|
||||
|
||||
m_ref = ref;
|
||||
m_type = type;
|
||||
|
||||
AddRefHandle();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void* CScriptHandle::GetRef() { return m_ref; }
|
||||
void CScriptHandle::Set(void *ref, asITypeInfo *type)
|
||||
{
|
||||
if( m_ref == ref ) return;
|
||||
|
||||
asITypeInfo* CScriptHandle::GetType() const { return m_type; }
|
||||
ReleaseHandle();
|
||||
|
||||
int CScriptHandle::GetTypeId() const {
|
||||
if (m_type == 0)
|
||||
return 0;
|
||||
m_ref = ref;
|
||||
m_type = type;
|
||||
|
||||
return m_type->GetTypeId() | asTYPEID_OBJHANDLE;
|
||||
AddRefHandle();
|
||||
}
|
||||
|
||||
// This method shouldn't be called from the application
|
||||
void *CScriptHandle::GetRef()
|
||||
{
|
||||
return m_ref;
|
||||
}
|
||||
|
||||
asITypeInfo *CScriptHandle::GetType() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
int CScriptHandle::GetTypeId() const
|
||||
{
|
||||
if( m_type == 0 ) return 0;
|
||||
|
||||
return m_type->GetTypeId() | asTYPEID_OBJHANDLE;
|
||||
}
|
||||
|
||||
// This method shouldn't be called from the application
|
||||
// directly as it requires an active script context
|
||||
CScriptHandle& CScriptHandle::Assign(void* ref, int typeId) {
|
||||
// When receiving a null handle we just clear our memory
|
||||
if (typeId == 0) {
|
||||
Set(0, 0);
|
||||
return *this;
|
||||
}
|
||||
CScriptHandle &CScriptHandle::Assign(void *ref, int typeId)
|
||||
{
|
||||
// When receiving a null handle we just clear our memory
|
||||
if( typeId == 0 )
|
||||
{
|
||||
Set(0, 0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Dereference received handles to get the object
|
||||
if (typeId & asTYPEID_OBJHANDLE) {
|
||||
// Store the actual reference
|
||||
ref = *(void**)ref;
|
||||
typeId &= ~asTYPEID_OBJHANDLE;
|
||||
}
|
||||
// Dereference received handles to get the object
|
||||
if( typeId & asTYPEID_OBJHANDLE )
|
||||
{
|
||||
// Store the actual reference
|
||||
ref = *(void**)ref;
|
||||
typeId &= ~asTYPEID_OBJHANDLE;
|
||||
}
|
||||
|
||||
// Get the object type
|
||||
asIScriptContext* ctx = asGetActiveContext();
|
||||
asIScriptEngine* engine = ctx->GetEngine();
|
||||
asITypeInfo* type = engine->GetTypeInfoById(typeId);
|
||||
// Get the object type
|
||||
asIScriptContext *ctx = asGetActiveContext();
|
||||
asIScriptEngine *engine = ctx->GetEngine();
|
||||
asITypeInfo *type = engine->GetTypeInfoById(typeId);
|
||||
|
||||
// If the argument is another CScriptHandle, we should copy the content instead
|
||||
if (type && strcmp(type->GetName(), "ref") == 0) {
|
||||
CScriptHandle* r = (CScriptHandle*)ref;
|
||||
ref = r->m_ref;
|
||||
type = r->m_type;
|
||||
}
|
||||
// If the argument is another CScriptHandle, we should copy the content instead
|
||||
if( type && strcmp(type->GetName(), "ref") == 0 )
|
||||
{
|
||||
CScriptHandle *r = (CScriptHandle*)ref;
|
||||
ref = r->m_ref;
|
||||
type = r->m_type;
|
||||
}
|
||||
|
||||
Set(ref, type);
|
||||
Set(ref, type);
|
||||
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool CScriptHandle::operator==(const CScriptHandle& o) const {
|
||||
if (m_ref == o.m_ref && m_type == o.m_type)
|
||||
return true;
|
||||
bool CScriptHandle::operator==(const CScriptHandle &o) const
|
||||
{
|
||||
if( m_ref == o.m_ref &&
|
||||
m_type == o.m_type )
|
||||
return true;
|
||||
|
||||
// TODO: If type is not the same, we should attempt to do a dynamic cast,
|
||||
// which may change the pointer for application registered classes
|
||||
// TODO: If type is not the same, we should attempt to do a dynamic cast,
|
||||
// which may change the pointer for application registered classes
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CScriptHandle::operator!=(const CScriptHandle& o) const { return !(*this == o); }
|
||||
bool CScriptHandle::operator!=(const CScriptHandle &o) const
|
||||
{
|
||||
return !(*this == o);
|
||||
}
|
||||
|
||||
bool CScriptHandle::Equals(void* ref, int typeId) const {
|
||||
// Null handles are received as reference to a null handle
|
||||
if (typeId == 0)
|
||||
ref = 0;
|
||||
bool CScriptHandle::Equals(void *ref, int typeId) const
|
||||
{
|
||||
// Null handles are received as reference to a null handle
|
||||
if( typeId == 0 )
|
||||
ref = 0;
|
||||
|
||||
// Dereference handles to get the object
|
||||
if (typeId & asTYPEID_OBJHANDLE) {
|
||||
// Compare the actual reference
|
||||
ref = *(void**)ref;
|
||||
typeId &= ~asTYPEID_OBJHANDLE;
|
||||
}
|
||||
// Dereference handles to get the object
|
||||
if( typeId & asTYPEID_OBJHANDLE )
|
||||
{
|
||||
// Compare the actual reference
|
||||
ref = *(void**)ref;
|
||||
typeId &= ~asTYPEID_OBJHANDLE;
|
||||
}
|
||||
|
||||
// TODO: If typeId is not the same, we should attempt to do a dynamic cast,
|
||||
// which may change the pointer for application registered classes
|
||||
// TODO: If typeId is not the same, we should attempt to do a dynamic cast,
|
||||
// which may change the pointer for application registered classes
|
||||
|
||||
if (ref == m_ref)
|
||||
return true;
|
||||
if( ref == m_ref ) return true;
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// AngelScript: used as '@obj = cast<obj>(ref);'
|
||||
void CScriptHandle::Cast(void** outRef, int typeId) {
|
||||
// If we hold a null handle, then just return null
|
||||
if (m_type == 0) {
|
||||
*outRef = 0;
|
||||
return;
|
||||
}
|
||||
void CScriptHandle::Cast(void **outRef, int typeId)
|
||||
{
|
||||
// If we hold a null handle, then just return null
|
||||
if( m_type == 0 )
|
||||
{
|
||||
*outRef = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// It is expected that the outRef is always a handle
|
||||
assert( typeId & asTYPEID_OBJHANDLE );
|
||||
|
||||
// It is expected that the outRef is always a handle
|
||||
assert(typeId & asTYPEID_OBJHANDLE);
|
||||
// Compare the type id of the actual object
|
||||
typeId &= ~asTYPEID_OBJHANDLE;
|
||||
asIScriptEngine *engine = m_type->GetEngine();
|
||||
asITypeInfo *type = engine->GetTypeInfoById(typeId);
|
||||
|
||||
// Compare the type id of the actual object
|
||||
typeId &= ~asTYPEID_OBJHANDLE;
|
||||
asIScriptEngine* engine = m_type->GetEngine();
|
||||
asITypeInfo* type = engine->GetTypeInfoById(typeId);
|
||||
*outRef = 0;
|
||||
|
||||
*outRef = 0;
|
||||
|
||||
// RefCastObject will increment the refCount of the returned object if successful
|
||||
engine->RefCastObject(m_ref, m_type, type, outRef);
|
||||
// RefCastObject will increment the refCount of the returned object if successful
|
||||
engine->RefCastObject(m_ref, m_type, type, outRef);
|
||||
}
|
||||
|
||||
void CScriptHandle::EnumReferences(asIScriptEngine* inEngine) {
|
||||
// If we're holding a reference, we'll notify the garbage collector of it
|
||||
if (m_ref)
|
||||
inEngine->GCEnumCallback(m_ref);
|
||||
void CScriptHandle::EnumReferences(asIScriptEngine *inEngine)
|
||||
{
|
||||
// If we're holding a reference, we'll notify the garbage collector of it
|
||||
if (m_ref)
|
||||
inEngine->GCEnumCallback(m_ref);
|
||||
|
||||
// The object type itself is also garbage collected
|
||||
if (m_type)
|
||||
inEngine->GCEnumCallback(m_type);
|
||||
// The object type itself is also garbage collected
|
||||
if( m_type)
|
||||
inEngine->GCEnumCallback(m_type);
|
||||
}
|
||||
|
||||
void CScriptHandle::ReleaseReferences(asIScriptEngine*) {
|
||||
// Simply clear the content to release the references
|
||||
Set(0, 0);
|
||||
void CScriptHandle::ReleaseReferences(asIScriptEngine *inEngine)
|
||||
{
|
||||
// Simply clear the content to release the references
|
||||
Set(0, 0);
|
||||
}
|
||||
|
||||
void RegisterScriptHandle_Native(asIScriptEngine* engine) {
|
||||
[[maybe_unused]] int r;
|
||||
void RegisterScriptHandle_Native(asIScriptEngine *engine)
|
||||
{
|
||||
int r;
|
||||
|
||||
#if AS_CAN_USE_CPP11
|
||||
// With C++11 it is possible to use asGetTypeTraits to automatically determine the flags that represent the C++
|
||||
// class
|
||||
r = engine->RegisterObjectType("ref", sizeof(CScriptHandle),
|
||||
asOBJ_VALUE | asOBJ_ASHANDLE | asOBJ_GC | asGetTypeTraits<CScriptHandle>());
|
||||
assert(r >= 0);
|
||||
// With C++11 it is possible to use asGetTypeTraits to automatically determine the flags that represent the C++ class
|
||||
r = engine->RegisterObjectType("ref", sizeof(CScriptHandle), asOBJ_VALUE | asOBJ_ASHANDLE | asOBJ_GC | asGetTypeTraits<CScriptHandle>()); assert( r >= 0 );
|
||||
#else
|
||||
r = engine->RegisterObjectType("ref", sizeof(CScriptHandle),
|
||||
asOBJ_VALUE | asOBJ_ASHANDLE | asOBJ_GC | asOBJ_APP_CLASS_CDAK);
|
||||
assert(r >= 0);
|
||||
r = engine->RegisterObjectType("ref", sizeof(CScriptHandle), asOBJ_VALUE | asOBJ_ASHANDLE | asOBJ_GC | asOBJ_APP_CLASS_CDAK); assert( r >= 0 );
|
||||
#endif
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_CONSTRUCT, "void f()",
|
||||
asFUNCTIONPR(Construct, (CScriptHandle*), void), asCALL_CDECL_OBJFIRST);
|
||||
assert(r >= 0);
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_CONSTRUCT, "void f(const ref &in)",
|
||||
asFUNCTIONPR(Construct, (CScriptHandle*, const CScriptHandle&), void),
|
||||
asCALL_CDECL_OBJFIRST);
|
||||
assert(r >= 0);
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_CONSTRUCT, "void f(const ?&in)",
|
||||
asFUNCTIONPR(Construct, (CScriptHandle*, void*, int), void),
|
||||
asCALL_CDECL_OBJFIRST);
|
||||
assert(r >= 0);
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_DESTRUCT, "void f()",
|
||||
asFUNCTIONPR(Destruct, (CScriptHandle*), void), asCALL_CDECL_OBJFIRST);
|
||||
assert(r >= 0);
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_ENUMREFS, "void f(int&in)",
|
||||
asMETHOD(CScriptHandle, EnumReferences), asCALL_THISCALL);
|
||||
assert(r >= 0);
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_RELEASEREFS, "void f(int&in)",
|
||||
asMETHOD(CScriptHandle, ReleaseReferences), asCALL_THISCALL);
|
||||
assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("ref", "void opCast(?&out)", asMETHODPR(CScriptHandle, Cast, (void**, int), void),
|
||||
asCALL_THISCALL);
|
||||
assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("ref", "ref &opHndlAssign(const ref &in)", asMETHOD(CScriptHandle, operator=),
|
||||
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 ?&in) const",
|
||||
asMETHODPR(CScriptHandle, Equals, (void*, int)const, bool), asCALL_THISCALL);
|
||||
assert(r >= 0);
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_CONSTRUCT, "void f()", asFUNCTIONPR(Construct, (CScriptHandle *), void), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_CONSTRUCT, "void f(const ref &in)", asFUNCTIONPR(Construct, (CScriptHandle *, const CScriptHandle &), void), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_CONSTRUCT, "void f(const ?&in)", asFUNCTIONPR(Construct, (CScriptHandle *, void *, int), void), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_DESTRUCT, "void f()", asFUNCTIONPR(Destruct, (CScriptHandle *), void), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_ENUMREFS, "void f(int&in)", asMETHOD(CScriptHandle,EnumReferences), asCALL_THISCALL); assert(r >= 0);
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_RELEASEREFS, "void f(int&in)", asMETHOD(CScriptHandle, ReleaseReferences), asCALL_THISCALL); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("ref", "void opCast(?&out)", asMETHODPR(CScriptHandle, Cast, (void **, int), void), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("ref", "ref &opHndlAssign(const ref &in)", asMETHOD(CScriptHandle, operator=), 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 ?&in) const", asMETHODPR(CScriptHandle, Equals, (void*, int) const, bool), asCALL_THISCALL); assert( r >= 0 );
|
||||
}
|
||||
|
||||
void CScriptHandle_Construct_Generic(asIScriptGeneric* gen) {
|
||||
CScriptHandle* self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
new (self) CScriptHandle();
|
||||
void CScriptHandle_Construct_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
new(self) CScriptHandle();
|
||||
}
|
||||
|
||||
void CScriptHandle_ConstructCopy_Generic(asIScriptGeneric* gen) {
|
||||
CScriptHandle* other = reinterpret_cast<CScriptHandle*>(gen->GetArgAddress(0));
|
||||
CScriptHandle* self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
new (self) CScriptHandle(*other);
|
||||
void CScriptHandle_ConstructCopy_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptHandle *other = reinterpret_cast<CScriptHandle*>(gen->GetArgAddress(0));
|
||||
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
new(self) CScriptHandle(*other);
|
||||
}
|
||||
|
||||
void CScriptHandle_ConstructVar_Generic(asIScriptGeneric* gen) {
|
||||
void* ref = gen->GetArgAddress(0);
|
||||
int typeId = gen->GetArgTypeId(0);
|
||||
CScriptHandle* self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
Construct(self, ref, typeId);
|
||||
void CScriptHandle_ConstructVar_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
void *ref = gen->GetArgAddress(0);
|
||||
int typeId = gen->GetArgTypeId(0);
|
||||
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
Construct(self, ref, typeId);
|
||||
}
|
||||
|
||||
void CScriptHandle_Destruct_Generic(asIScriptGeneric* gen) {
|
||||
CScriptHandle* self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
self->~CScriptHandle();
|
||||
void CScriptHandle_Destruct_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
self->~CScriptHandle();
|
||||
}
|
||||
|
||||
void CScriptHandle_Cast_Generic(asIScriptGeneric* gen) {
|
||||
void** ref = reinterpret_cast<void**>(gen->GetArgAddress(0));
|
||||
int typeId = gen->GetArgTypeId(0);
|
||||
CScriptHandle* self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
self->Cast(ref, typeId);
|
||||
void CScriptHandle_Cast_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
void **ref = reinterpret_cast<void**>(gen->GetArgAddress(0));
|
||||
int typeId = gen->GetArgTypeId(0);
|
||||
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
self->Cast(ref, typeId);
|
||||
}
|
||||
|
||||
void CScriptHandle_Assign_Generic(asIScriptGeneric* gen) {
|
||||
CScriptHandle* other = reinterpret_cast<CScriptHandle*>(gen->GetArgAddress(0));
|
||||
CScriptHandle* self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
*self = *other;
|
||||
gen->SetReturnAddress(self);
|
||||
void CScriptHandle_Assign_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptHandle *other = reinterpret_cast<CScriptHandle*>(gen->GetArgAddress(0));
|
||||
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
*self = *other;
|
||||
gen->SetReturnAddress(self);
|
||||
}
|
||||
|
||||
void CScriptHandle_AssignVar_Generic(asIScriptGeneric* gen) {
|
||||
void* ref = gen->GetArgAddress(0);
|
||||
int typeId = gen->GetArgTypeId(0);
|
||||
CScriptHandle* self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
self->Assign(ref, typeId);
|
||||
gen->SetReturnAddress(self);
|
||||
void CScriptHandle_AssignVar_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
void *ref = gen->GetArgAddress(0);
|
||||
int typeId = gen->GetArgTypeId(0);
|
||||
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
self->Assign(ref, typeId);
|
||||
gen->SetReturnAddress(self);
|
||||
}
|
||||
|
||||
void CScriptHandle_Equals_Generic(asIScriptGeneric* gen) {
|
||||
CScriptHandle* other = reinterpret_cast<CScriptHandle*>(gen->GetArgAddress(0));
|
||||
CScriptHandle* self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
gen->SetReturnByte(*self == *other);
|
||||
void CScriptHandle_Equals_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptHandle *other = reinterpret_cast<CScriptHandle*>(gen->GetArgAddress(0));
|
||||
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
gen->SetReturnByte(*self == *other);
|
||||
}
|
||||
|
||||
void CScriptHandle_EqualsVar_Generic(asIScriptGeneric* gen) {
|
||||
void* ref = gen->GetArgAddress(0);
|
||||
int typeId = gen->GetArgTypeId(0);
|
||||
CScriptHandle* self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
gen->SetReturnByte(self->Equals(ref, typeId));
|
||||
void CScriptHandle_EqualsVar_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
void *ref = gen->GetArgAddress(0);
|
||||
int typeId = gen->GetArgTypeId(0);
|
||||
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
gen->SetReturnByte(self->Equals(ref, typeId));
|
||||
}
|
||||
|
||||
void CScriptHandle_EnumReferences_Generic(asIScriptGeneric* gen) {
|
||||
CScriptHandle* self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
self->EnumReferences(gen->GetEngine());
|
||||
void CScriptHandle_EnumReferences_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
self->EnumReferences(gen->GetEngine());
|
||||
}
|
||||
|
||||
void CScriptHandle_ReleaseReferences_Generic(asIScriptGeneric* gen) {
|
||||
CScriptHandle* self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
self->ReleaseReferences(gen->GetEngine());
|
||||
void CScriptHandle_ReleaseReferences_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
self->ReleaseReferences(gen->GetEngine());
|
||||
}
|
||||
|
||||
void RegisterScriptHandle_Generic(asIScriptEngine* engine) {
|
||||
[[maybe_unused]] int r;
|
||||
void RegisterScriptHandle_Generic(asIScriptEngine *engine)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = engine->RegisterObjectType("ref", sizeof(CScriptHandle),
|
||||
asOBJ_VALUE | asOBJ_ASHANDLE | asOBJ_GC | asOBJ_APP_CLASS_CDAK);
|
||||
assert(r >= 0);
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_CONSTRUCT, "void f()",
|
||||
asFUNCTION(CScriptHandle_Construct_Generic), asCALL_GENERIC);
|
||||
assert(r >= 0);
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_CONSTRUCT, "void f(const ref &in)",
|
||||
asFUNCTION(CScriptHandle_ConstructCopy_Generic), asCALL_GENERIC);
|
||||
assert(r >= 0);
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_CONSTRUCT, "void f(const ?&in)",
|
||||
asFUNCTION(CScriptHandle_ConstructVar_Generic), asCALL_GENERIC);
|
||||
assert(r >= 0);
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_DESTRUCT, "void f()",
|
||||
asFUNCTION(CScriptHandle_Destruct_Generic), asCALL_GENERIC);
|
||||
assert(r >= 0);
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_ENUMREFS, "void f(int&in)",
|
||||
asFUNCTION(CScriptHandle_EnumReferences_Generic), asCALL_GENERIC);
|
||||
assert(r >= 0);
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_RELEASEREFS, "void f(int&in)",
|
||||
asFUNCTION(CScriptHandle_ReleaseReferences_Generic), asCALL_GENERIC);
|
||||
assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("ref", "void opCast(?&out)", asFUNCTION(CScriptHandle_Cast_Generic),
|
||||
asCALL_GENERIC);
|
||||
assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("ref", "ref &opHndlAssign(const ref &in)",
|
||||
asFUNCTION(CScriptHandle_Assign_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 ?&in) const",
|
||||
asFUNCTION(CScriptHandle_EqualsVar_Generic), asCALL_GENERIC);
|
||||
assert(r >= 0);
|
||||
r = engine->RegisterObjectType("ref", sizeof(CScriptHandle), asOBJ_VALUE | asOBJ_ASHANDLE | asOBJ_GC | asOBJ_APP_CLASS_CDAK); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(CScriptHandle_Construct_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_CONSTRUCT, "void f(const ref &in)", asFUNCTION(CScriptHandle_ConstructCopy_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_CONSTRUCT, "void f(const ?&in)", asFUNCTION(CScriptHandle_ConstructVar_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(CScriptHandle_Destruct_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_ENUMREFS, "void f(int&in)", asFUNCTION(CScriptHandle_EnumReferences_Generic), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_RELEASEREFS, "void f(int&in)", asFUNCTION(CScriptHandle_ReleaseReferences_Generic), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("ref", "void opCast(?&out)", asFUNCTION(CScriptHandle_Cast_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("ref", "ref &opHndlAssign(const ref &in)", asFUNCTION(CScriptHandle_Assign_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 ?&in) const", asFUNCTION(CScriptHandle_EqualsVar_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
}
|
||||
|
||||
void RegisterScriptHandle(asIScriptEngine* engine) {
|
||||
if (strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY"))
|
||||
RegisterScriptHandle_Generic(engine);
|
||||
else
|
||||
RegisterScriptHandle_Native(engine);
|
||||
void RegisterScriptHandle(asIScriptEngine *engine)
|
||||
{
|
||||
if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
|
||||
RegisterScriptHandle_Generic(engine);
|
||||
else
|
||||
RegisterScriptHandle_Native(engine);
|
||||
}
|
||||
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
|
|
@ -975,8 +975,7 @@ string ScriptGetExceptionInfo()
|
|||
|
||||
void RegisterExceptionRoutines(asIScriptEngine *engine)
|
||||
{
|
||||
[[maybe_unused]]
|
||||
int r;
|
||||
int r;
|
||||
|
||||
// The string type must be available
|
||||
assert(engine->GetTypeInfoByDecl("string"));
|
||||
|
|
|
@ -28,25 +28,26 @@ typedef map<string, int> map_t;
|
|||
END_AS_NAMESPACE
|
||||
#endif
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
class CStdStringFactory : public asIStringFactory
|
||||
{
|
||||
public:
|
||||
CStdStringFactory() = default;
|
||||
~CStdStringFactory() override
|
||||
CStdStringFactory() {}
|
||||
~CStdStringFactory()
|
||||
{
|
||||
// The script engine must release each string
|
||||
// constant that it has requested
|
||||
assert(stringCache.empty());
|
||||
assert(stringCache.size() == 0);
|
||||
}
|
||||
|
||||
const void *GetStringConstant(const char *data, asUINT length) override
|
||||
const void *GetStringConstant(const char *data, asUINT length)
|
||||
{
|
||||
// The string factory might be modified from multiple
|
||||
// threads, so it is necessary to use a mutex.
|
||||
asAcquireExclusiveLock();
|
||||
|
||||
string str(data, length);
|
||||
auto it = stringCache.find(str);
|
||||
map_t::iterator it = stringCache.find(str);
|
||||
if (it != stringCache.end())
|
||||
it->second++;
|
||||
else
|
||||
|
@ -57,9 +58,9 @@ public:
|
|||
return reinterpret_cast<const void*>(&it->first);
|
||||
}
|
||||
|
||||
int ReleaseStringConstant(const void *str) override
|
||||
int ReleaseStringConstant(const void *str)
|
||||
{
|
||||
if (str == nullptr)
|
||||
if (str == 0)
|
||||
return asERROR;
|
||||
|
||||
int ret = asSUCCESS;
|
||||
|
@ -68,7 +69,7 @@ public:
|
|||
// threads, so it is necessary to use a mutex.
|
||||
asAcquireExclusiveLock();
|
||||
|
||||
auto it = stringCache.find(*reinterpret_cast<const string*>(str));
|
||||
map_t::iterator it = stringCache.find(*reinterpret_cast<const string*>(str));
|
||||
if (it == stringCache.end())
|
||||
ret = asERROR;
|
||||
else
|
||||
|
@ -83,9 +84,9 @@ public:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int GetRawStringData(const void *str, char *data, asUINT *length) const override
|
||||
int GetRawStringData(const void *str, char *data, asUINT *length) const
|
||||
{
|
||||
if (str == nullptr)
|
||||
if (str == 0)
|
||||
return asERROR;
|
||||
|
||||
if (length)
|
||||
|
@ -98,17 +99,17 @@ public:
|
|||
}
|
||||
|
||||
// THe access to the string cache is protected with the common mutex provided by AngelScript
|
||||
map_t stringCache = {};
|
||||
map_t stringCache;
|
||||
};
|
||||
|
||||
static CStdStringFactory *stringFactory = nullptr;
|
||||
static CStdStringFactory *stringFactory = 0;
|
||||
|
||||
// TODO: Make this public so the application can also use the string
|
||||
// factory and share the string constants if so desired, or to
|
||||
// monitor the size of the string factory cache.
|
||||
CStdStringFactory *GetStdStringFactorySingleton()
|
||||
{
|
||||
if( stringFactory == nullptr )
|
||||
if( stringFactory == 0 )
|
||||
{
|
||||
// The following instance will be destroyed by the global
|
||||
// CStdStringFactoryCleaner instance upon application shutdown
|
||||
|
@ -122,7 +123,7 @@ class CStdStringFactoryCleaner
|
|||
public:
|
||||
~CStdStringFactoryCleaner()
|
||||
{
|
||||
if (stringFactory != nullptr)
|
||||
if (stringFactory)
|
||||
{
|
||||
// Only delete the string factory if the stringCache is empty
|
||||
// If it is not empty, it means that someone might still attempt
|
||||
|
@ -133,13 +134,13 @@ public:
|
|||
if (stringFactory->stringCache.empty())
|
||||
{
|
||||
delete stringFactory;
|
||||
stringFactory = nullptr;
|
||||
stringFactory = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static CStdStringFactoryCleaner cleaner = {};
|
||||
static CStdStringFactoryCleaner cleaner;
|
||||
|
||||
|
||||
static void ConstructString(string *thisPointer)
|
||||
|
@ -461,12 +462,12 @@ static void StringResize(asUINT l, string &str)
|
|||
// string formatInt(int64 val, const string &in options, uint width)
|
||||
static string formatInt(asINT64 value, const string &options, asUINT width)
|
||||
{
|
||||
bool leftJustify = options.find('l') != string::npos;
|
||||
bool padWithZero = options.find('0') != string::npos;
|
||||
bool alwaysSign = options.find('+') != string::npos;
|
||||
bool spaceOnSign = options.find(' ') != string::npos;
|
||||
bool hexSmall = options.find('h') != string::npos;
|
||||
bool hexLarge = options.find('H') != string::npos;
|
||||
bool leftJustify = options.find("l") != string::npos;
|
||||
bool padWithZero = options.find("0") != string::npos;
|
||||
bool alwaysSign = options.find("+") != string::npos;
|
||||
bool spaceOnSign = options.find(" ") != string::npos;
|
||||
bool hexSmall = options.find("h") != string::npos;
|
||||
bool hexLarge = options.find("H") != string::npos;
|
||||
|
||||
string fmt = "%";
|
||||
if( leftJustify ) fmt += "-";
|
||||
|
@ -505,12 +506,12 @@ static string formatInt(asINT64 value, const string &options, asUINT width)
|
|||
// string formatUInt(uint64 val, const string &in options, uint width)
|
||||
static string formatUInt(asQWORD value, const string &options, asUINT width)
|
||||
{
|
||||
bool leftJustify = options.find('l') != string::npos;
|
||||
bool padWithZero = options.find('0') != string::npos;
|
||||
bool alwaysSign = options.find('+') != string::npos;
|
||||
bool spaceOnSign = options.find(' ') != string::npos;
|
||||
bool hexSmall = options.find('h') != string::npos;
|
||||
bool hexLarge = options.find('H') != string::npos;
|
||||
bool leftJustify = options.find("l") != string::npos;
|
||||
bool padWithZero = options.find("0") != string::npos;
|
||||
bool alwaysSign = options.find("+") != string::npos;
|
||||
bool spaceOnSign = options.find(" ") != string::npos;
|
||||
bool hexSmall = options.find("h") != string::npos;
|
||||
bool hexLarge = options.find("H") != string::npos;
|
||||
|
||||
string fmt = "%";
|
||||
if( leftJustify ) fmt += "-";
|
||||
|
@ -549,12 +550,12 @@ static string formatUInt(asQWORD value, const string &options, asUINT width)
|
|||
// string formatFloat(double val, const string &in options, uint width, uint precision)
|
||||
static string formatFloat(double value, const string &options, asUINT width, asUINT precision)
|
||||
{
|
||||
bool leftJustify = options.find('l') != string::npos;
|
||||
bool padWithZero = options.find('0') != string::npos;
|
||||
bool alwaysSign = options.find('+') != string::npos;
|
||||
bool spaceOnSign = options.find(' ') != string::npos;
|
||||
bool expSmall = options.find('e') != string::npos;
|
||||
bool expLarge = options.find('E') != string::npos;
|
||||
bool leftJustify = options.find("l") != string::npos;
|
||||
bool padWithZero = options.find("0") != string::npos;
|
||||
bool alwaysSign = options.find("+") != string::npos;
|
||||
bool spaceOnSign = options.find(" ") != string::npos;
|
||||
bool expSmall = options.find("e") != string::npos;
|
||||
bool expLarge = options.find("E") != string::npos;
|
||||
|
||||
string fmt = "%";
|
||||
if( leftJustify ) fmt += "-";
|
||||
|
@ -734,7 +735,7 @@ static string StringSubString(asUINT start, int count, const string &str)
|
|||
// makro, so this wrapper was introduced as work around.
|
||||
static bool StringEquals(const std::string& lhs, const std::string& rhs)
|
||||
{
|
||||
return lhs == rhs;
|
||||
return lhs == rhs;
|
||||
}
|
||||
|
||||
void RegisterStdString_Native(asIScriptEngine *engine)
|
||||
|
|
|
@ -112,8 +112,7 @@ static void StringJoin_Generic(asIScriptGeneric *gen)
|
|||
// The string type must have been registered first.
|
||||
void RegisterStdStringUtils(asIScriptEngine *engine)
|
||||
{
|
||||
[[maybe_unused]]
|
||||
int r;
|
||||
int r;
|
||||
|
||||
if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2019 Andreas Jonsson
|
||||
Copyright (c) 2003-2020 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
|
@ -58,8 +58,8 @@ BEGIN_AS_NAMESPACE
|
|||
|
||||
// AngelScript version
|
||||
|
||||
#define ANGELSCRIPT_VERSION 23400
|
||||
#define ANGELSCRIPT_VERSION_STRING "2.34.0"
|
||||
#define ANGELSCRIPT_VERSION 23500
|
||||
#define ANGELSCRIPT_VERSION_STRING "2.35.0"
|
||||
|
||||
// Data types
|
||||
|
||||
|
@ -195,6 +195,7 @@ enum asEObjTypeFlags
|
|||
asOBJ_APP_CLASS_A = (asOBJ_APP_CLASS + asOBJ_APP_CLASS_ASSIGNMENT),
|
||||
asOBJ_APP_CLASS_AK = (asOBJ_APP_CLASS + asOBJ_APP_CLASS_ASSIGNMENT + asOBJ_APP_CLASS_COPY_CONSTRUCTOR),
|
||||
asOBJ_APP_CLASS_K = (asOBJ_APP_CLASS + asOBJ_APP_CLASS_COPY_CONSTRUCTOR),
|
||||
asOBJ_APP_CLASS_MORE_CONSTRUCTORS = (1<<31),
|
||||
asOBJ_APP_PRIMITIVE = (1<<13),
|
||||
asOBJ_APP_FLOAT = (1<<14),
|
||||
asOBJ_APP_ARRAY = (1<<15),
|
||||
|
@ -203,7 +204,7 @@ enum asEObjTypeFlags
|
|||
asOBJ_NOCOUNT = (1<<18),
|
||||
asOBJ_APP_CLASS_ALIGN8 = (1<<19),
|
||||
asOBJ_IMPLICIT_HANDLE = (1<<20),
|
||||
asOBJ_MASK_VALID_FLAGS = 0x1FFFFF,
|
||||
asOBJ_MASK_VALID_FLAGS = 0x801FFFFF,
|
||||
// Internal flags
|
||||
asOBJ_SCRIPT_OBJECT = (1<<21),
|
||||
asOBJ_SHARED = (1<<22),
|
||||
|
@ -385,7 +386,7 @@ typedef unsigned int asUINT;
|
|||
#endif
|
||||
|
||||
// Is the target a 64bit system?
|
||||
#if defined(__LP64__) || defined(__amd64__) || defined(__x86_64__) || defined(_M_X64)
|
||||
#if defined(__LP64__) || defined(__amd64__) || defined(__x86_64__) || defined(_M_X64) || defined(__aarch64__) || defined(_M_ARM64)
|
||||
#ifndef AS_64BIT_PTR
|
||||
#define AS_64BIT_PTR
|
||||
#endif
|
||||
|
@ -1015,7 +1016,7 @@ public:
|
|||
|
||||
// Miscellaneous
|
||||
virtual asIScriptEngine *GetEngine() const = 0;
|
||||
virtual int CopyFrom(asIScriptObject *other) = 0;
|
||||
virtual int CopyFrom(const asIScriptObject *other) = 0;
|
||||
|
||||
// User data
|
||||
virtual void *SetUserData(void *data, asPWORD type = 0) = 0;
|
||||
|
@ -1238,7 +1239,7 @@ template <int N>
|
|||
struct asSMethodPtr
|
||||
{
|
||||
template<class M>
|
||||
static asSFuncPtr Convert(M)
|
||||
static asSFuncPtr Convert(M Mthd)
|
||||
{
|
||||
// This version of the function should never be executed, nor compiled,
|
||||
// as it would mean that the size of the method pointer cannot be determined.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2019 Andreas Jonsson
|
||||
Copyright (c) 2003-2020 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
|
@ -386,7 +386,7 @@ int asCBuilder::CompileGlobalVar(const char *sectionName, const char *code, int
|
|||
|
||||
node = node->firstChild;
|
||||
node->DisconnectParent();
|
||||
RegisterGlobalVar(node, script, module->defaultNamespace);
|
||||
RegisterGlobalVar(node, script, module->m_defaultNamespace);
|
||||
|
||||
CompileGlobalVariables();
|
||||
|
||||
|
@ -410,10 +410,10 @@ int asCBuilder::CompileGlobalVar(const char *sectionName, const char *code, int
|
|||
for( asUINT n = 0; n < functions.GetLength(); n++ )
|
||||
{
|
||||
asCScriptFunction *func = engine->scriptFunctions[functions[n]->funcId];
|
||||
if( module->globalFunctions.GetIndex(func) >= 0 )
|
||||
if( module->m_globalFunctions.GetIndex(func) >= 0 )
|
||||
{
|
||||
module->globalFunctions.Erase(module->globalFunctions.GetIndex(func));
|
||||
module->scriptFunctions.RemoveValue(func);
|
||||
module->m_globalFunctions.Erase(module->m_globalFunctions.GetIndex(func));
|
||||
module->m_scriptFunctions.RemoveValue(func);
|
||||
func->ReleaseInternal();
|
||||
}
|
||||
}
|
||||
|
@ -552,13 +552,13 @@ int asCBuilder::CompileFunction(const char *sectionName, const char *code, int l
|
|||
if( func == 0 )
|
||||
return asOUT_OF_MEMORY;
|
||||
|
||||
GetParsedFunctionDetails(node, scripts[0], 0, func->name, func->returnType, func->parameterNames, func->parameterTypes, func->inOutFlags, func->defaultArgs, funcTraits, module->defaultNamespace);
|
||||
GetParsedFunctionDetails(node, scripts[0], 0, func->name, func->returnType, func->parameterNames, func->parameterTypes, func->inOutFlags, func->defaultArgs, funcTraits, module->m_defaultNamespace);
|
||||
func->id = engine->GetNextScriptFunctionId();
|
||||
func->scriptData->scriptSectionIdx = engine->GetScriptSectionNameIndex(sectionName ? sectionName : "");
|
||||
int row, col;
|
||||
scripts[0]->ConvertPosToRowCol(node->tokenPos, &row, &col);
|
||||
func->scriptData->declaredAt = (row & 0xFFFFF)|((col & 0xFFF)<<20);
|
||||
func->nameSpace = module->defaultNamespace;
|
||||
func->nameSpace = module->m_defaultNamespace;
|
||||
|
||||
// Make sure the default args are declared correctly
|
||||
int r = ValidateDefaultArgs(script, node, func);
|
||||
|
@ -571,14 +571,14 @@ int asCBuilder::CompileFunction(const char *sectionName, const char *code, int l
|
|||
// Tell the engine that the function exists already so the compiler can access it
|
||||
if( compileFlags & asCOMP_ADD_TO_MODULE )
|
||||
{
|
||||
r = CheckNameConflict(func->name.AddressOf(), node, scripts[0], module->defaultNamespace, false, false);
|
||||
r = CheckNameConflict(func->name.AddressOf(), node, scripts[0], module->m_defaultNamespace, false, false);
|
||||
if( r < 0 )
|
||||
{
|
||||
func->ReleaseInternal();
|
||||
return asERROR;
|
||||
}
|
||||
|
||||
module->globalFunctions.Put(func);
|
||||
module->m_globalFunctions.Put(func);
|
||||
|
||||
module->AddScriptFunction(func);
|
||||
}
|
||||
|
@ -622,10 +622,10 @@ int asCBuilder::CompileFunction(const char *sectionName, const char *code, int l
|
|||
for( asUINT n = 0; n < functions.GetLength(); n++ )
|
||||
{
|
||||
asCScriptFunction *f = engine->scriptFunctions[functions[n]->funcId];
|
||||
if( module->globalFunctions.GetIndex(f) >= 0 )
|
||||
if( module->m_globalFunctions.GetIndex(f) >= 0 )
|
||||
{
|
||||
module->globalFunctions.Erase(module->globalFunctions.GetIndex(f));
|
||||
module->scriptFunctions.RemoveValue(f);
|
||||
module->m_globalFunctions.Erase(module->m_globalFunctions.GetIndex(f));
|
||||
module->m_scriptFunctions.RemoveValue(f);
|
||||
f->ReleaseInternal();
|
||||
}
|
||||
}
|
||||
|
@ -1096,7 +1096,7 @@ asCObjectProperty *asCBuilder::GetObjectProperty(asCDataType &obj, const char *p
|
|||
{
|
||||
if( props[n]->name == prop )
|
||||
{
|
||||
if( module->accessMask & props[n]->accessMask )
|
||||
if( module->m_accessMask & props[n]->accessMask )
|
||||
return props[n];
|
||||
else
|
||||
return 0;
|
||||
|
@ -1137,7 +1137,7 @@ bool asCBuilder::DoesGlobalPropertyExist(const char *prop, asSNameSpace *ns, asC
|
|||
// Check previously compiled global variables
|
||||
if( module )
|
||||
{
|
||||
globProp = module->scriptGlobals.GetFirst(ns, prop);
|
||||
globProp = module->m_scriptGlobals.GetFirst(ns, prop);
|
||||
if( globProp )
|
||||
{
|
||||
if( outProp ) *outProp = globProp;
|
||||
|
@ -1172,7 +1172,7 @@ asCGlobalProperty *asCBuilder::GetGlobalProperty(const char *prop, asSNameSpace
|
|||
if( isAppProp )
|
||||
{
|
||||
// Don't return the property if the module doesn't have access to it
|
||||
if( !(module->accessMask & globProp->accessMask) )
|
||||
if( !(module->m_accessMask & globProp->accessMask) )
|
||||
globProp = 0;
|
||||
}
|
||||
return globProp;
|
||||
|
@ -1649,7 +1649,7 @@ int asCBuilder::CheckNameConflict(const char *name, asCScriptNode *node, asCScri
|
|||
for( n = 0; n < funcDefs.GetLength(); n++ )
|
||||
{
|
||||
if( funcDefs[n]->name == name &&
|
||||
module->funcDefs[funcDefs[n]->idx]->nameSpace == ns )
|
||||
module->m_funcDefs[funcDefs[n]->idx]->nameSpace == ns )
|
||||
{
|
||||
if( code )
|
||||
{
|
||||
|
@ -1915,7 +1915,7 @@ void asCBuilder::CompleteFuncDef(sFuncDef *funcDef)
|
|||
asCArray<asCString *> defaultArgs;
|
||||
asSFunctionTraits funcTraits;
|
||||
|
||||
asCFuncdefType *fdt = module->funcDefs[funcDef->idx];
|
||||
asCFuncdefType *fdt = module->m_funcDefs[funcDef->idx];
|
||||
asASSERT( fdt );
|
||||
asCScriptFunction *func = fdt->funcdef;
|
||||
|
||||
|
@ -1972,7 +1972,7 @@ void asCBuilder::CompleteFuncDef(sFuncDef *funcDef)
|
|||
{
|
||||
// Replace our funcdef for the existing one
|
||||
funcDef->idx = fdt2->funcdef->id;
|
||||
module->funcDefs[module->funcDefs.IndexOf(fdt)] = fdt2;
|
||||
module->ReplaceFuncDef(fdt, fdt2);
|
||||
fdt2->AddRefInternal();
|
||||
|
||||
engine->funcDefs.RemoveValue(fdt);
|
||||
|
@ -1994,7 +1994,7 @@ void asCBuilder::CompleteFuncDef(sFuncDef *funcDef)
|
|||
|
||||
// Remember if the type was declared as external so the saved bytecode can be flagged accordingly
|
||||
if (funcTraits.GetTrait(asTRAIT_EXTERNAL) && found)
|
||||
module->externalTypes.PushLast(engine->scriptFunctions[funcDef->idx]->funcdefType);
|
||||
module->m_externalTypes.PushLast(engine->scriptFunctions[funcDef->idx]->funcdefType);
|
||||
}
|
||||
|
||||
int asCBuilder::RegisterGlobalVar(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns)
|
||||
|
@ -2259,7 +2259,7 @@ int asCBuilder::RegisterClass(asCScriptNode *node, asCScriptCode *file, asSNameS
|
|||
// We'll use the existing type
|
||||
decl->isExistingShared = true;
|
||||
decl->typeInfo = st;
|
||||
module->classTypes.PushLast(st);
|
||||
module->AddClassType(st);
|
||||
st->AddRefInternal();
|
||||
break;
|
||||
}
|
||||
|
@ -2276,7 +2276,7 @@ int asCBuilder::RegisterClass(asCScriptNode *node, asCScriptCode *file, asSNameS
|
|||
|
||||
// Remember if the class was declared as external so the saved bytecode can be flagged accordingly
|
||||
if (isExternal)
|
||||
module->externalTypes.PushLast(st);
|
||||
module->m_externalTypes.PushLast(st);
|
||||
|
||||
if (!decl->isExistingShared)
|
||||
{
|
||||
|
@ -2310,7 +2310,7 @@ int asCBuilder::RegisterClass(asCScriptNode *node, asCScriptCode *file, asSNameS
|
|||
st->name = name;
|
||||
st->nameSpace = ns;
|
||||
st->module = module;
|
||||
module->classTypes.PushLast(st);
|
||||
module->AddClassType(st);
|
||||
if (isShared)
|
||||
{
|
||||
engine->sharedScriptTypes.PushLast(st);
|
||||
|
@ -2429,12 +2429,12 @@ int asCBuilder::RegisterInterface(asCScriptNode *node, asCScriptCode *file, asSN
|
|||
// We'll use the existing type
|
||||
decl->isExistingShared = true;
|
||||
decl->typeInfo = st;
|
||||
module->classTypes.PushLast(st);
|
||||
module->AddClassType(st);
|
||||
st->AddRefInternal();
|
||||
|
||||
// Remember if the interface was declared as external so the saved bytecode can be flagged accordingly
|
||||
if (isExternal)
|
||||
module->externalTypes.PushLast(st);
|
||||
module->m_externalTypes.PushLast(st);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2463,7 +2463,7 @@ int asCBuilder::RegisterInterface(asCScriptNode *node, asCScriptCode *file, asSN
|
|||
st->name = name;
|
||||
st->nameSpace = ns;
|
||||
st->module = module;
|
||||
module->classTypes.PushLast(st);
|
||||
module->AddClassType(st);
|
||||
if( isShared )
|
||||
{
|
||||
engine->sharedScriptTypes.PushLast(st);
|
||||
|
@ -2751,8 +2751,8 @@ void asCBuilder::CompileGlobalVariables()
|
|||
// If the length of the arrays are not the same, then this is the compilation
|
||||
// of a single variable, in which case the initialization order of the previous
|
||||
// variables must be preserved.
|
||||
if( module->scriptGlobals.GetSize() == initOrder.GetSize() )
|
||||
module->scriptGlobals.SwapWith(initOrder);
|
||||
if( module->m_scriptGlobals.GetSize() == initOrder.GetSize() )
|
||||
module->m_scriptGlobals.SwapWith(initOrder);
|
||||
}
|
||||
|
||||
CleanupEnumValues();
|
||||
|
@ -4320,7 +4320,7 @@ int asCBuilder::RegisterEnum(asCScriptNode *node, asCScriptCode *file, asSNameSp
|
|||
|
||||
// Remember if the type was declared as external so the saved bytecode can be flagged accordingly
|
||||
if (isExternal && existingSharedType)
|
||||
module->externalTypes.PushLast(existingSharedType);
|
||||
module->m_externalTypes.PushLast(existingSharedType);
|
||||
|
||||
// Check the name and add the enum
|
||||
int r = CheckNameConflict(name.AddressOf(), tmp->firstChild, file, ns, true, false);
|
||||
|
@ -4347,7 +4347,7 @@ int asCBuilder::RegisterEnum(asCScriptNode *node, asCScriptCode *file, asSNameSp
|
|||
st->nameSpace = ns;
|
||||
st->module = module;
|
||||
}
|
||||
module->enumTypes.PushLast(st);
|
||||
module->AddEnumType(st);
|
||||
|
||||
if( !existingSharedType && isShared )
|
||||
{
|
||||
|
@ -4513,7 +4513,7 @@ int asCBuilder::RegisterTypedef(asCScriptNode *node, asCScriptCode *file, asSNam
|
|||
st->aliasForType = dataType;
|
||||
st->module = module;
|
||||
|
||||
module->typeDefs.PushLast(st);
|
||||
module->AddTypeDef(st);
|
||||
|
||||
// Store the location of this declaration for reference in name collisions
|
||||
sClassDeclaration *decl = asNEW(sClassDeclaration);
|
||||
|
@ -4968,7 +4968,7 @@ int asCBuilder::RegisterScriptFunction(asCScriptNode *node, asCScriptCode *file,
|
|||
|
||||
// Remember if the function was declared as external so the saved bytecode can be flagged accordingly
|
||||
if (funcTraits.GetTrait(asTRAIT_EXTERNAL) && func->isExistingShared)
|
||||
module->externalFunctions.PushLast(engine->scriptFunctions[func->funcId]);
|
||||
module->m_externalFunctions.PushLast(engine->scriptFunctions[func->funcId]);
|
||||
|
||||
if (funcTraits.GetTrait(asTRAIT_EXTERNAL) && !func->isExistingShared)
|
||||
{
|
||||
|
@ -5099,7 +5099,7 @@ int asCBuilder::RegisterScriptFunction(asCScriptNode *node, asCScriptCode *file,
|
|||
module->AddScriptFunction(f);
|
||||
|
||||
// TODO: clean up: This should be done by AddScriptFunction() itself
|
||||
module->globalFunctions.Put(f);
|
||||
module->m_globalFunctions.Put(f);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5136,7 +5136,9 @@ int asCBuilder::RegisterScriptFunction(asCScriptNode *node, asCScriptCode *file,
|
|||
else
|
||||
{
|
||||
// The copy constructor needs to be marked for easy finding
|
||||
if (parameterTypes.GetLength() == 1 && parameterTypes[0].GetTypeInfo() == objType)
|
||||
if( parameterTypes.GetLength() == 1 &&
|
||||
parameterTypes[0].GetTypeInfo() == objType &&
|
||||
(parameterTypes[0].IsReference() || parameterTypes[0].IsObjectHandle()) )
|
||||
{
|
||||
// Verify that there are not multiple options matching the copy constructor
|
||||
// TODO: Need a better message, since the parameters can be slightly different, e.g. & vs @
|
||||
|
@ -5423,21 +5425,21 @@ void asCBuilder::GetFunctionDescriptions(const char *name, asCArray<int> &funcs,
|
|||
asUINT n;
|
||||
|
||||
// Get the script declared global functions
|
||||
const asCArray<unsigned int> &idxs = module->globalFunctions.GetIndexes(ns, name);
|
||||
const asCArray<unsigned int> &idxs = module->m_globalFunctions.GetIndexes(ns, name);
|
||||
for( n = 0; n < idxs.GetLength(); n++ )
|
||||
{
|
||||
const asCScriptFunction *f = module->globalFunctions.Get(idxs[n]);
|
||||
const asCScriptFunction *f = module->m_globalFunctions.Get(idxs[n]);
|
||||
asASSERT( f->objectType == 0 );
|
||||
funcs.PushLast(f->id);
|
||||
}
|
||||
|
||||
// Add the imported functions
|
||||
// TODO: optimize: Linear search: This is probably not that critial. Also bindInformation will probably be removed in near future
|
||||
for( n = 0; n < module->bindInformations.GetLength(); n++ )
|
||||
for( n = 0; n < module->m_bindInformations.GetLength(); n++ )
|
||||
{
|
||||
if( module->bindInformations[n]->importedFunctionSignature->name == name &&
|
||||
module->bindInformations[n]->importedFunctionSignature->nameSpace == ns )
|
||||
funcs.PushLast(module->bindInformations[n]->importedFunctionSignature->id);
|
||||
if( module->m_bindInformations[n]->importedFunctionSignature->name == name &&
|
||||
module->m_bindInformations[n]->importedFunctionSignature->nameSpace == ns )
|
||||
funcs.PushLast(module->m_bindInformations[n]->importedFunctionSignature->id);
|
||||
}
|
||||
|
||||
// Add the registered global functions
|
||||
|
@ -5447,7 +5449,7 @@ void asCBuilder::GetFunctionDescriptions(const char *name, asCArray<int> &funcs,
|
|||
asCScriptFunction *f = engine->registeredGlobalFuncs.Get(idxs2[n]);
|
||||
|
||||
// Verify if the module has access to the function
|
||||
if( module->accessMask & f->accessMask )
|
||||
if( module->m_accessMask & f->accessMask )
|
||||
{
|
||||
funcs.PushLast(f->id);
|
||||
}
|
||||
|
@ -5508,7 +5510,7 @@ void asCBuilder::GetObjectMethodDescriptions(const char *name, asCObjectType *ob
|
|||
asCScriptFunction *func = engine->scriptFunctions[objectType->methods[n]];
|
||||
if( func->name == name &&
|
||||
(!objIsConst || func->IsReadOnly()) &&
|
||||
(func->accessMask & module->accessMask) )
|
||||
(func->accessMask & module->m_accessMask) )
|
||||
{
|
||||
// When the scope is defined the returned methods should be the true methods, not the virtual method stubs
|
||||
if( scope == "" )
|
||||
|
@ -5845,7 +5847,7 @@ asCDataType asCBuilder::CreateDataTypeFromNode(asCScriptNode *node, asCScriptCod
|
|||
isImplicitHandle = true;
|
||||
|
||||
// Make sure the module has access to the object type
|
||||
if( !module || (module->accessMask & ti->accessMask) )
|
||||
if( !module || (module->m_accessMask & ti->accessMask) )
|
||||
{
|
||||
if( asOBJ_TYPEDEF == (ti->flags & asOBJ_TYPEDEF) )
|
||||
{
|
||||
|
@ -6266,24 +6268,24 @@ bool asCBuilder::DoesTypeExist(const asCString &type)
|
|||
if (module)
|
||||
{
|
||||
// Add script classes and interfaces
|
||||
for (n = 0; n < module->classTypes.GetLength(); n++)
|
||||
if (!knownTypes.MoveTo(0, module->classTypes[n]->name))
|
||||
knownTypes.Insert(module->classTypes[n]->name, true);
|
||||
for (n = 0; n < module->m_classTypes.GetLength(); n++)
|
||||
if (!knownTypes.MoveTo(0, module->m_classTypes[n]->name))
|
||||
knownTypes.Insert(module->m_classTypes[n]->name, true);
|
||||
|
||||
// Add script enums
|
||||
for (n = 0; n < module->enumTypes.GetLength(); n++)
|
||||
if (!knownTypes.MoveTo(0, module->enumTypes[n]->name))
|
||||
knownTypes.Insert(module->enumTypes[n]->name, true);
|
||||
for (n = 0; n < module->m_enumTypes.GetLength(); n++)
|
||||
if (!knownTypes.MoveTo(0, module->m_enumTypes[n]->name))
|
||||
knownTypes.Insert(module->m_enumTypes[n]->name, true);
|
||||
|
||||
// Add script typedefs
|
||||
for (n = 0; n < module->typeDefs.GetLength(); n++)
|
||||
if (!knownTypes.MoveTo(0, module->typeDefs[n]->name))
|
||||
knownTypes.Insert(module->typeDefs[n]->name, true);
|
||||
for (n = 0; n < module->m_typeDefs.GetLength(); n++)
|
||||
if (!knownTypes.MoveTo(0, module->m_typeDefs[n]->name))
|
||||
knownTypes.Insert(module->m_typeDefs[n]->name, true);
|
||||
|
||||
// Add script funcdefs
|
||||
for (n = 0; n < module->funcDefs.GetLength(); n++)
|
||||
if (!knownTypes.MoveTo(0, module->funcDefs[n]->name))
|
||||
knownTypes.Insert(module->funcDefs[n]->name, true);
|
||||
for (n = 0; n < module->m_funcDefs.GetLength(); n++)
|
||||
if (!knownTypes.MoveTo(0, module->m_funcDefs[n]->name))
|
||||
knownTypes.Insert(module->m_funcDefs[n]->name, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6346,9 +6348,9 @@ asCFuncdefType *asCBuilder::GetFuncDef(const char *type, asSNameSpace *ns, asCOb
|
|||
|
||||
if (module)
|
||||
{
|
||||
for (asUINT n = 0; n < module->funcDefs.GetLength(); n++)
|
||||
for (asUINT n = 0; n < module->m_funcDefs.GetLength(); n++)
|
||||
{
|
||||
asCFuncdefType *funcDef = module->funcDefs[n];
|
||||
asCFuncdefType *funcDef = module->m_funcDefs[n];
|
||||
if (funcDef && funcDef->nameSpace == ns && funcDef->name == type)
|
||||
return funcDef;
|
||||
}
|
||||
|
@ -6405,7 +6407,7 @@ int asCBuilder::GetEnumValue(const char *name, asCDataType &outDt, asDWORD &outV
|
|||
if( ns != et->nameSpace ) continue;
|
||||
|
||||
// Don't bother with types the module doesn't have access to
|
||||
if( (et->accessMask & module->accessMask) == 0 )
|
||||
if( (et->accessMask & module->m_accessMask) == 0 )
|
||||
continue;
|
||||
|
||||
if( GetEnumValueFromType(et, name, outDt, outValue) )
|
||||
|
@ -6420,9 +6422,9 @@ int asCBuilder::GetEnumValue(const char *name, asCDataType &outDt, asDWORD &outV
|
|||
}
|
||||
}
|
||||
|
||||
for( t = 0; t < module->enumTypes.GetLength(); t++ )
|
||||
for( t = 0; t < module->m_enumTypes.GetLength(); t++ )
|
||||
{
|
||||
asCEnumType *et = module->enumTypes[t];
|
||||
asCEnumType *et = module->m_enumTypes[t];
|
||||
if( ns != et->nameSpace ) continue;
|
||||
|
||||
if( GetEnumValueFromType(et, name, outDt, outValue) )
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2019 Andreas Jonsson
|
||||
Copyright (c) 2003-2020 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
|
@ -135,7 +135,7 @@ int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv,
|
|||
internal->callConv = (internalCallConv)(thisCallConv + 2);
|
||||
#endif
|
||||
internal->baseOffset = ( int )MULTI_BASE_OFFSET(ptr);
|
||||
#if (defined(AS_ARM) || defined(AS_MIPS)) && (defined(__GNUC__) || defined(AS_PSVITA))
|
||||
#if (defined(AS_ARM64) || defined(AS_ARM) || defined(AS_MIPS)) && (defined(__GNUC__) || defined(AS_PSVITA))
|
||||
// As the least significant bit in func is used to switch to THUMB mode
|
||||
// on ARM processors, the LSB in the __delta variable is used instead of
|
||||
// the one in __pfn on ARM processors.
|
||||
|
@ -619,7 +619,7 @@ int CallSystemFunction(int id, asCContext *context)
|
|||
}
|
||||
|
||||
// Add the base offset for multiple inheritance
|
||||
#if (defined(__GNUC__) && (defined(AS_ARM) || defined(AS_MIPS))) || defined(AS_PSVITA)
|
||||
#if (defined(__GNUC__) && (defined(AS_ARM64) || defined(AS_ARM) || defined(AS_MIPS))) || defined(AS_PSVITA)
|
||||
// On GNUC + ARM the lsb of the offset is used to indicate a virtual function
|
||||
// and the whole offset is thus shifted one bit left to keep the original
|
||||
// offset resolution
|
||||
|
@ -653,7 +653,7 @@ int CallSystemFunction(int id, asCContext *context)
|
|||
if( obj )
|
||||
{
|
||||
// Add the base offset for multiple inheritance
|
||||
#if (defined(__GNUC__) && (defined(AS_ARM) || defined(AS_MIPS))) || defined(AS_PSVITA)
|
||||
#if (defined(__GNUC__) && (defined(AS_ARM64) || defined(AS_ARM) || defined(AS_MIPS))) || defined(AS_PSVITA)
|
||||
// On GNUC + ARM the lsb of the offset is used to indicate a virtual function
|
||||
// and the whole offset is thus shifted one bit left to keep the original
|
||||
// offset resolution
|
||||
|
@ -680,7 +680,7 @@ int CallSystemFunction(int id, asCContext *context)
|
|||
}
|
||||
|
||||
// Add the base offset for multiple inheritance
|
||||
#if (defined(__GNUC__) && (defined(AS_ARM) || defined(AS_MIPS))) || defined(AS_PSVITA)
|
||||
#if (defined(__GNUC__) && (defined(AS_ARM64) || defined(AS_ARM) || defined(AS_MIPS))) || defined(AS_PSVITA)
|
||||
// On GNUC + ARM the lsb of the offset is used to indicate a virtual function
|
||||
// and the whole offset is thus shifted one bit left to keep the original
|
||||
// offset resolution
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2017 Andreas Jonsson
|
||||
Copyright (c) 2003-2020 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
|
@ -100,7 +100,6 @@ struct asSSystemFunctionInterface
|
|||
asFUNCTION_t func;
|
||||
int baseOffset;
|
||||
internalCallConv callConv;
|
||||
int scriptReturnSize;
|
||||
bool hostReturnInMemory;
|
||||
bool hostReturnFloat;
|
||||
int hostReturnSize;
|
||||
|
@ -120,7 +119,7 @@ struct asSSystemFunctionInterface
|
|||
};
|
||||
asCArray<SClean> cleanArgs;
|
||||
|
||||
asSSystemFunctionInterface() : func(0), baseOffset(0), callConv(ICC_GENERIC_FUNC), scriptReturnSize(0), hostReturnInMemory(false), hostReturnFloat(false), hostReturnSize(0), paramSize(0), takesObjByVal(false), returnAutoHandle(false), compositeOffset(0), isCompositeIndirect(false), auxiliary(0) {}
|
||||
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(const asSSystemFunctionInterface &in)
|
||||
{
|
||||
|
@ -132,7 +131,6 @@ struct asSSystemFunctionInterface
|
|||
func = in.func;
|
||||
baseOffset = in.baseOffset;
|
||||
callConv = in.callConv;
|
||||
scriptReturnSize = in.scriptReturnSize;
|
||||
hostReturnInMemory = in.hostReturnInMemory;
|
||||
hostReturnFloat = in.hostReturnFloat;
|
||||
hostReturnSize = in.hostReturnSize;
|
||||
|
|
|
@ -0,0 +1,329 @@
|
|||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2020-2020 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you
|
||||
must not claim that you wrote the original software. If you use
|
||||
this software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
The original version of this library can be located at:
|
||||
http://www.angelcode.com/angelscript/
|
||||
|
||||
Andreas Jonsson
|
||||
andreas@angelcode.com
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// as_callfunc_arm64.cpp
|
||||
//
|
||||
// These functions handle the actual calling of system functions on the arm64 platform
|
||||
//
|
||||
// Written by Max Waine in July 2020, based on as_callfunc_arm.cpp
|
||||
//
|
||||
|
||||
|
||||
#include "as_config.h"
|
||||
|
||||
#ifndef AS_MAX_PORTABILITY
|
||||
#ifdef AS_ARM64
|
||||
|
||||
#include "as_callfunc.h"
|
||||
#include "as_scriptengine.h"
|
||||
#include "as_texts.h"
|
||||
#include "as_tokendef.h"
|
||||
#include "as_context.h"
|
||||
|
||||
// ARM64 targets use has no software floating-point ABI, it's all hardware (or totally disabled)
|
||||
|
||||
#define HFA_RET_REGISTERS 4 // s0-s3/d0-d3
|
||||
#define GP_ARG_REGISTERS 8 // x0-x7
|
||||
#define FLOAT_ARG_REGISTERS 8 // v0-v7
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
// x0-7: Argument registers (pass params or return results. OK as volatile local variables)
|
||||
// x8: Indirect result register (e.g. address of large returned struct)
|
||||
// x9-15: Volatile local variable registers
|
||||
// x16-17: Intra-procedure-call temporary registers
|
||||
// x18: Platform register (reserved for use of platform ABIs)
|
||||
// x19-29: Non-volatile variable registers (must be saved and restored if modified)
|
||||
// x29: Frame pointer register
|
||||
// x30: Link register (where to return to)
|
||||
|
||||
extern "C" void GetHFAReturnDouble(asQWORD *out1, asQWORD *out2, asQWORD returnSize);
|
||||
extern "C" void GetHFAReturnFloat(asQWORD *out1, asQWORD *out2, asQWORD returnSize);
|
||||
|
||||
extern "C" asQWORD CallARM64RetInMemory(
|
||||
const asQWORD *gpRegArgs, asQWORD numGPRegArgs,
|
||||
const asQWORD *floatRegArgs, asQWORD numFloatRegArgs,
|
||||
const asQWORD *stackArgs, asQWORD numStackArgs,
|
||||
void *retPointer, asFUNCTION_t func
|
||||
);
|
||||
extern "C" double CallARM64Double(
|
||||
const asQWORD *gpRegArgs, asQWORD numGPRegArgs,
|
||||
const asQWORD *floatRegArgs, asQWORD numFloatRegArgs,
|
||||
const asQWORD *stackArgs, asQWORD numStackArgs,
|
||||
asFUNCTION_t func
|
||||
);
|
||||
extern "C" float CallARM64Float(
|
||||
const asQWORD *gpRegArgs, asQWORD numGPRegArgs,
|
||||
const asQWORD *floatRegArgs, asQWORD numFloatRegArgs,
|
||||
const asQWORD *stackArgs, asQWORD numStackArgs,
|
||||
asFUNCTION_t func
|
||||
);
|
||||
extern "C" asQWORD CallARM64(
|
||||
const asQWORD *gpRegArgs, asQWORD numGPRegArgs,
|
||||
const asQWORD *floatRegArgs, asQWORD numFloatRegArgs,
|
||||
const asQWORD *stackArgs, asQWORD numStackArgs,
|
||||
asFUNCTION_t func
|
||||
);
|
||||
extern "C" asQWORD CallARM64Ret128(
|
||||
const asQWORD *gpRegArgs, asQWORD numGPRegArgs,
|
||||
const asQWORD *floatRegArgs, asQWORD numFloatRegArgs,
|
||||
const asQWORD *stackArgs, asQWORD numStackArgs,
|
||||
asQWORD *higherQWORD, asFUNCTION_t func
|
||||
);
|
||||
|
||||
//
|
||||
// If it's possible to fit in registers,
|
||||
// there may not be enough float register space even if true is returned
|
||||
//
|
||||
static inline bool IsRegisterHFA(const asCDataType &type)
|
||||
{
|
||||
const asCTypeInfo *const typeInfo = type.GetTypeInfo();
|
||||
|
||||
if( typeInfo == nullptr ||
|
||||
(typeInfo->flags & asOBJ_APP_CLASS_ALLFLOATS) == 0 ||
|
||||
type.IsObjectHandle() && type.IsReference() )
|
||||
return false;
|
||||
|
||||
const bool doubles = (typeInfo->flags & asOBJ_APP_CLASS_ALIGN8) != 0;
|
||||
const int maxAllowedSize = doubles ? sizeof(double) * HFA_RET_REGISTERS : sizeof(float) * HFA_RET_REGISTERS;
|
||||
|
||||
return type.GetSizeInMemoryBytes() <= maxAllowedSize;
|
||||
}
|
||||
|
||||
//
|
||||
// If it's possible to fit it in registers,
|
||||
// if true is returned there is enough space to fit
|
||||
//
|
||||
static inline bool IsRegisterHFAParameter(const asCDataType &type, const asQWORD numFloatRegArgs)
|
||||
{
|
||||
if( !IsRegisterHFA(type) )
|
||||
return false;
|
||||
|
||||
const bool doubles = (type.GetTypeInfo()->flags & asOBJ_APP_CLASS_ALIGN8) != 0;
|
||||
const int registersUsed = type.GetSizeInMemoryDWords() / (doubles ? sizeof(double) : sizeof(float));
|
||||
|
||||
return numFloatRegArgs + registersUsed <= FLOAT_ARG_REGISTERS;
|
||||
}
|
||||
|
||||
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &retQW2, void *secondObject)
|
||||
{
|
||||
asCScriptEngine *engine = context->m_engine;
|
||||
const asSSystemFunctionInterface *const sysFunc = descr->sysFuncIntf;
|
||||
const asCDataType &retType = descr->returnType;
|
||||
const asCTypeInfo *const retTypeInfo = retType.GetTypeInfo();
|
||||
asFUNCTION_t func = sysFunc->func;
|
||||
int callConv = sysFunc->callConv;
|
||||
asQWORD retQW = 0;
|
||||
|
||||
asQWORD gpRegArgs[GP_ARG_REGISTERS];
|
||||
asQWORD floatRegArgs[FLOAT_ARG_REGISTERS];
|
||||
asQWORD stackArgs[64]; // It's how many x64 users can have
|
||||
asQWORD numGPRegArgs = 0;
|
||||
asQWORD numFloatRegArgs = 0;
|
||||
asQWORD numStackArgs = 0;
|
||||
|
||||
asFUNCTION_t *vftable;
|
||||
|
||||
// Optimization to avoid check 12 values (all ICC_ that contains THISCALL)
|
||||
if( (callConv >= ICC_THISCALL && callConv <= ICC_VIRTUAL_THISCALL_RETURNINMEM) ||
|
||||
(callConv >= ICC_THISCALL_OBJLAST && callConv <= ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM) )
|
||||
{
|
||||
// Add the object pointer as the first parameter
|
||||
gpRegArgs[numGPRegArgs++] = (asQWORD)obj;
|
||||
}
|
||||
|
||||
if( callConv == ICC_CDECL_OBJFIRST || callConv == ICC_CDECL_OBJFIRST_RETURNINMEM )
|
||||
{
|
||||
// Add the object pointer as the first parameter
|
||||
gpRegArgs[numGPRegArgs++] = (asQWORD)obj;
|
||||
}
|
||||
else if( callConv == ICC_THISCALL_OBJFIRST || callConv == ICC_THISCALL_OBJFIRST_RETURNINMEM ||
|
||||
callConv == ICC_VIRTUAL_THISCALL_OBJFIRST || callConv == ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM )
|
||||
{
|
||||
// Add the object pointer as the first parameter
|
||||
gpRegArgs[numGPRegArgs++] = (asQWORD)secondObject;
|
||||
}
|
||||
|
||||
if( callConv == ICC_VIRTUAL_THISCALL || callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM || callConv == ICC_VIRTUAL_THISCALL_OBJFIRST ||
|
||||
callConv == ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM || callConv == ICC_VIRTUAL_THISCALL_OBJLAST || callConv == ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM )
|
||||
{
|
||||
// Get virtual function table from the object pointer
|
||||
vftable = *(asFUNCTION_t**)obj;
|
||||
func = vftable[FuncPtrToUInt(func)/sizeof(void*)];
|
||||
}
|
||||
|
||||
asUINT argsPos = 0;
|
||||
for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
|
||||
{
|
||||
const asCDataType &parmType = descr->parameterTypes[n];
|
||||
const asCTypeInfo *const parmTypeInfo = parmType.GetTypeInfo();
|
||||
|
||||
if( parmType.IsObject() && !parmType.IsObjectHandle() && !parmType.IsReference() )
|
||||
{
|
||||
const asUINT parmDWords = parmType.GetSizeInMemoryDWords();
|
||||
const asUINT parmQWords = (parmDWords >> 1) + (parmDWords & 1);
|
||||
|
||||
const bool passedAsPointer = parmQWords <= 2;
|
||||
const bool fitsInRegisters = passedAsPointer ? (numGPRegArgs < GP_ARG_REGISTERS) : (numGPRegArgs + parmQWords <= GP_ARG_REGISTERS);
|
||||
asQWORD *const argsArray = fitsInRegisters ? gpRegArgs : stackArgs;
|
||||
asQWORD &numArgs = fitsInRegisters ? numGPRegArgs : numStackArgs;
|
||||
|
||||
if( (parmTypeInfo->flags & COMPLEX_MASK) )
|
||||
{
|
||||
argsArray[numArgs++] = *(asQWORD*)&args[argsPos];
|
||||
argsPos += AS_PTR_SIZE;
|
||||
}
|
||||
else if( IsRegisterHFAParameter(parmType, numFloatRegArgs) )
|
||||
{
|
||||
if( (parmTypeInfo->flags & asOBJ_APP_CLASS_ALIGN8) != 0 )
|
||||
{
|
||||
const asQWORD *const contents = *(asQWORD**)&args[argsPos];
|
||||
for( asUINT i = 0; i < parmQWords; i++ )
|
||||
floatRegArgs[numFloatRegArgs++] = *(asQWORD*)&contents[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
const asDWORD *const contents = *(asDWORD**)&args[argsPos];
|
||||
for( asUINT i = 0; i < parmDWords; i++ )
|
||||
floatRegArgs[numFloatRegArgs++] = *(asQWORD*)&contents[i];
|
||||
}
|
||||
engine->CallFree(*(char**)(args+argsPos));
|
||||
argsPos += AS_PTR_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Copy the object's memory to the buffer
|
||||
memcpy(&argsArray[numArgs], *(void**)(args+argsPos), parmType.GetSizeInMemoryBytes());
|
||||
|
||||
// Delete the original memory
|
||||
engine->CallFree(*(char**)(args+argsPos));
|
||||
argsPos += AS_PTR_SIZE;
|
||||
numArgs += parmQWords;
|
||||
}
|
||||
}
|
||||
else if( parmType.IsFloatType() && !parmType.IsReference() )
|
||||
{
|
||||
if( numFloatRegArgs >= FLOAT_ARG_REGISTERS )
|
||||
stackArgs[numStackArgs++] = args[argsPos];
|
||||
else
|
||||
floatRegArgs[numFloatRegArgs++] = args[argsPos];
|
||||
argsPos++;
|
||||
}
|
||||
else if( parmType.IsDoubleType() && !parmType.IsReference() )
|
||||
{
|
||||
if( numFloatRegArgs >= FLOAT_ARG_REGISTERS )
|
||||
stackArgs[numStackArgs++] = *(asQWORD*)&args[argsPos];
|
||||
else
|
||||
floatRegArgs[numFloatRegArgs++] = *(asQWORD*)&args[argsPos];
|
||||
argsPos += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Copy the value directly
|
||||
const asUINT parmDWords = parmType.GetSizeOnStackDWords();
|
||||
const asUINT parmQWords = (parmDWords >> 1) + (parmDWords & 1);
|
||||
|
||||
const bool fitsInRegisters = numGPRegArgs + parmQWords <= GP_ARG_REGISTERS;
|
||||
asQWORD *const argsArray = fitsInRegisters ? gpRegArgs : stackArgs;
|
||||
asQWORD &numArgs = fitsInRegisters ? numGPRegArgs : numStackArgs;
|
||||
|
||||
memcpy(&argsArray[numArgs], (void*)(args+argsPos), parmDWords * 4);
|
||||
argsPos += parmDWords;
|
||||
numArgs += parmQWords;
|
||||
}
|
||||
}
|
||||
|
||||
if( callConv == ICC_CDECL_OBJLAST || callConv == ICC_CDECL_OBJLAST_RETURNINMEM )
|
||||
{
|
||||
// Add the object pointer as the last parameter
|
||||
if( numGPRegArgs < GP_ARG_REGISTERS )
|
||||
gpRegArgs[numGPRegArgs++] = (asQWORD)obj;
|
||||
else
|
||||
stackArgs[numStackArgs++] = (asQWORD)obj;
|
||||
}
|
||||
else if( callConv == ICC_THISCALL_OBJLAST || callConv == ICC_THISCALL_OBJLAST_RETURNINMEM ||
|
||||
callConv == ICC_VIRTUAL_THISCALL_OBJLAST || callConv == ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM )
|
||||
{
|
||||
// Add the object pointer as the last parameter
|
||||
if( numGPRegArgs < GP_ARG_REGISTERS )
|
||||
gpRegArgs[numGPRegArgs++] = (asQWORD)secondObject;
|
||||
else
|
||||
stackArgs[numStackArgs++] = (asQWORD)secondObject;
|
||||
}
|
||||
|
||||
if( IsRegisterHFA(retType) && !(retTypeInfo->flags & COMPLEX_MASK) )
|
||||
{
|
||||
// This is to deal with HFAs (Homogeneous Floating-point Aggregates):
|
||||
// ARM64 will place all-float composite types (of equal precision)
|
||||
// with <= 4 members in the float return registers
|
||||
|
||||
const int structSize = retType.GetSizeInMemoryBytes();
|
||||
|
||||
CallARM64(gpRegArgs, numGPRegArgs, floatRegArgs, numFloatRegArgs, stackArgs, numStackArgs, func);
|
||||
if( (retTypeInfo->flags & asOBJ_APP_CLASS_ALIGN8) != 0 )
|
||||
{
|
||||
if( structSize <= sizeof(double) * 2 )
|
||||
GetHFAReturnDouble(&retQW, &retQW2, structSize);
|
||||
else
|
||||
GetHFAReturnDouble((asQWORD*)retPointer, ((asQWORD*)retPointer) + 1, structSize);
|
||||
}
|
||||
else
|
||||
GetHFAReturnFloat(&retQW, &retQW2, structSize);
|
||||
}
|
||||
else if( sysFunc->hostReturnFloat )
|
||||
{
|
||||
if( sysFunc->hostReturnSize == 1 )
|
||||
*(float*)&retQW = CallARM64Float(gpRegArgs, numGPRegArgs, floatRegArgs, numFloatRegArgs, stackArgs, numStackArgs, func);
|
||||
else
|
||||
*(double*)&retQW = CallARM64Double(gpRegArgs, numGPRegArgs, floatRegArgs, numFloatRegArgs, stackArgs, numStackArgs, func);
|
||||
}
|
||||
else if( sysFunc->hostReturnInMemory )
|
||||
retQW = CallARM64RetInMemory(gpRegArgs, numGPRegArgs, floatRegArgs, numFloatRegArgs, stackArgs, numStackArgs, retPointer, func);
|
||||
else
|
||||
{
|
||||
if( retType.GetSizeInMemoryBytes() > sizeof(asQWORD) )
|
||||
retQW = CallARM64Ret128(gpRegArgs, numGPRegArgs, floatRegArgs, numFloatRegArgs, stackArgs, numStackArgs, &retQW2, func);
|
||||
else
|
||||
retQW = CallARM64(gpRegArgs, numGPRegArgs, floatRegArgs, numFloatRegArgs, stackArgs, numStackArgs, func);
|
||||
}
|
||||
|
||||
return retQW;
|
||||
}
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
#endif // AS_ARM64
|
||||
#endif // AS_MAX_PORTABILITY
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,219 @@
|
|||
//
|
||||
// AngelCode Scripting Library
|
||||
// Copyright (c) 2020-2020 Andreas Jonsson
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any
|
||||
// damages arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any
|
||||
// purpose, including commercial applications, and to alter it and
|
||||
// redistribute it freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented// you
|
||||
// must not claim that you wrote the original software. If you use
|
||||
// this software in a product, an acknowledgment in the product
|
||||
// documentation would be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and
|
||||
// must not be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
// The original version of this library can be located at:
|
||||
// http://www.angelcode.com/angelscript/
|
||||
//
|
||||
// Andreas Jonsson
|
||||
// andreas@angelcode.com
|
||||
//
|
||||
|
||||
|
||||
// Assembly routines for the ARM64/AArch64 call convention used for Linux
|
||||
// Written by Max Waine in July 2020, based on as_callfunc_arm_msvc.asm,
|
||||
// with assistance & guidance provided by Sir Kane
|
||||
|
||||
// Compile with GCC/GAS
|
||||
|
||||
.arch armv8-a
|
||||
.text
|
||||
|
||||
.global GetHFAReturnDouble
|
||||
.global GetHFAReturnFloat
|
||||
.global CallARM64Ret128
|
||||
.global CallARM64RetInMemory
|
||||
.global CallARM64Double
|
||||
.global CallARM64Float
|
||||
.global CallARM64
|
||||
|
||||
.type GetHFAReturnDouble, %function
|
||||
.type GetHFAReturnFloat, %function
|
||||
.type CallARM64Ret128, %function
|
||||
.type CallARM64RetInMemory, %function
|
||||
.type CallARM64Double, %function
|
||||
.type CallARM64Float, %function
|
||||
.type CallARM64, %function
|
||||
|
||||
.align 2
|
||||
GetHFAReturnDouble:
|
||||
adr x9, populateDoubles
|
||||
sub x9, x9, x1, lsr 1 // x9 -= returnSize >> 1; (/2 because double is 2x instruction size)
|
||||
br x9
|
||||
|
||||
str d3, [x0, #0x18]
|
||||
str d2, [x0, #0x10]
|
||||
str d1, [x1]
|
||||
str d0, [x0]
|
||||
populateDoubles:
|
||||
|
||||
ret
|
||||
|
||||
.align 2
|
||||
GetHFAReturnFloat:
|
||||
adr x9, populateFloats
|
||||
sub x9, x9, x2 // x9 -= returnSize; (already 4 bytes per return)
|
||||
br x9
|
||||
|
||||
str s3, [x1, #0x4]
|
||||
str s2, [x1]
|
||||
str s1, [x0, #0x4]
|
||||
str s0, [x0]
|
||||
populateFloats:
|
||||
|
||||
ret
|
||||
|
||||
|
||||
//[returnType] CallARM64[type](
|
||||
// const asQWORD *gpRegArgs, asQWORD numGPRegArgs,
|
||||
// const asQWORD *floatRegArgs, asQWORD numFloatRegArgs,
|
||||
// const asQWORD *stackArgs, asQWORD numStackArgs,
|
||||
// asFUNCTION_t func
|
||||
//)
|
||||
.align 2
|
||||
CallARM64Double:
|
||||
CallARM64Float:
|
||||
CallARM64:
|
||||
.cfi_startproc
|
||||
stp fp, lr, [sp,#-0x20]!
|
||||
str x20, [sp,#0x10]
|
||||
.cfi_def_cfa_offset 0x20
|
||||
.cfi_offset 20, 0x10
|
||||
.cfi_offset fp, -0x20
|
||||
.cfi_offset lr, -0x18
|
||||
mov fp, sp
|
||||
|
||||
mov x20, #0
|
||||
|
||||
cbz x5, stackArgsLoopEnd
|
||||
|
||||
// Align count to 2, then multiply by 8, resulting in a size aligned to 16
|
||||
add x20, x5, #1
|
||||
lsl x20, x20, #3
|
||||
and x20, x20, #-0x10
|
||||
// Multiply count by 8
|
||||
lsl x10, x5, #3
|
||||
sub sp, sp, x20
|
||||
stackArgsLoopStart:
|
||||
ldp x9,x11, [x4],#16
|
||||
stp x9,x11, [sp],#16
|
||||
subs x10, x10, #16
|
||||
bgt stackArgsLoopStart
|
||||
stackArgsLoopEnd:
|
||||
|
||||
// Calculate amount to jump forward, avoiding pointless instructions
|
||||
adr x9, populateFloatRegisterArgsEnd
|
||||
sub x9, x9, x3, lsl 2 // x9 -= numFloatRegArgs * 4
|
||||
br x9
|
||||
|
||||
ldr d7, [x2, #0x38]
|
||||
ldr d6, [x2, #0x30]
|
||||
ldr d5, [x2, #0x28]
|
||||
ldr d4, [x2, #0x20]
|
||||
ldr d3, [x2, #0x18]
|
||||
ldr d2, [x2, #0x10]
|
||||
ldr d1, [x2, #0x08]
|
||||
ldr d0, [x2]
|
||||
populateFloatRegisterArgsEnd:
|
||||
|
||||
mov x15, x6
|
||||
// Calculate amount to jump forward, avoiding pointless instructions
|
||||
adr x9, populateGPRegisterArgsEnd
|
||||
sub x9, x9, x1, lsl 2 // x9 -= numGPRegArgs * 4
|
||||
br x9
|
||||
|
||||
ldr x7, [x0, #0x38]
|
||||
ldr x6, [x0, #0x30]
|
||||
ldr x5, [x0, #0x28]
|
||||
ldr x4, [x0, #0x20]
|
||||
ldr x3, [x0, #0x18]
|
||||
ldr x2, [x0, #0x10]
|
||||
ldr x1, [x0, #0x08]
|
||||
ldr x0, [x0]
|
||||
populateGPRegisterArgsEnd:
|
||||
|
||||
// Actually call function
|
||||
sub sp, sp, x20
|
||||
blr x15
|
||||
add sp, sp, x20
|
||||
|
||||
ldr x20, [sp,#0x10]
|
||||
ldp fp, lr, [sp],#0x20
|
||||
|
||||
.cfi_restore lr
|
||||
.cfi_restore fp
|
||||
.cfi_restore 20
|
||||
.cfi_def_cfa_offset 0
|
||||
ret
|
||||
.cfi_endproc
|
||||
|
||||
.align 2
|
||||
CallARM64Ret128:
|
||||
.cfi_startproc
|
||||
stp fp, lr, [sp,#-0x20]!
|
||||
str x20, [sp,#0x10]
|
||||
.cfi_def_cfa_offset 0x20
|
||||
.cfi_offset 20, 0x10
|
||||
.cfi_offset fp, -0x20
|
||||
.cfi_offset lr, -0x18
|
||||
mov fp, sp
|
||||
|
||||
mov x20, x6
|
||||
mov x6, x7
|
||||
mov x7, #0
|
||||
bl CallARM64
|
||||
|
||||
str x1, [x20]
|
||||
|
||||
ldr x20, [sp,#0x10]
|
||||
ldp fp, lr, [sp],#0x20
|
||||
|
||||
.cfi_restore lr
|
||||
.cfi_restore fp
|
||||
.cfi_restore 20
|
||||
.cfi_def_cfa_offset 0
|
||||
ret
|
||||
.cfi_endproc
|
||||
|
||||
.align 2
|
||||
CallARM64RetInMemory:
|
||||
.cfi_startproc
|
||||
stp fp, lr, [sp,#-0x10]!
|
||||
mov fp, sp
|
||||
.cfi_def_cfa_offset 0x10
|
||||
.cfi_offset fp, -0x10
|
||||
.cfi_offset lr, -0x08
|
||||
|
||||
mov x8, x6
|
||||
mov x6, x7
|
||||
mov x7, #0
|
||||
bl CallARM64
|
||||
|
||||
mov x0, x8
|
||||
|
||||
ldp fp, lr, [sp],#0x10
|
||||
|
||||
.cfi_restore lr
|
||||
.cfi_restore fp
|
||||
.cfi_def_cfa_offset 0
|
||||
ret
|
||||
.cfi_endproc
|
|
@ -0,0 +1,205 @@
|
|||
;
|
||||
; AngelCode Scripting Library
|
||||
; Copyright (c) 2020-2020 Andreas Jonsson
|
||||
;
|
||||
; This software is provided 'as-is', without any express or implied
|
||||
; warranty. In no event will the authors be held liable for any
|
||||
; damages arising from the use of this software.
|
||||
;
|
||||
; Permission is granted to anyone to use this software for any
|
||||
; purpose, including commercial applications, and to alter it and
|
||||
; redistribute it freely, subject to the following restrictions:
|
||||
;
|
||||
; 1. The origin of this software must not be misrepresented; you
|
||||
; must not claim that you wrote the original software. If you use
|
||||
; this software in a product, an acknowledgment in the product
|
||||
; documentation would be appreciated but is not required.
|
||||
;
|
||||
; 2. Altered source versions must be plainly marked as such, and
|
||||
; must not be misrepresented as being the original software.
|
||||
;
|
||||
; 3. This notice may not be removed or altered from any source
|
||||
; distribution.
|
||||
;
|
||||
; The original version of this library can be located at:
|
||||
; http://www.angelcode.com/angelscript/
|
||||
;
|
||||
; Andreas Jonsson
|
||||
; andreas@angelcode.com
|
||||
;
|
||||
|
||||
|
||||
; Assembly routines for the ARM64/AArch64 call convention used for Windows 10 on ARM
|
||||
; Written by Max Waine in July 2020, based on as_callfunc_arm_msvc.asm
|
||||
|
||||
; MSVC currently doesn't support inline assembly for the ARM64 platform,
|
||||
; and if they're treating it like x64 /won't/ ever support inline assembly,
|
||||
; so this separate file is needed.
|
||||
|
||||
; Compile with Microsoft ARM64 assembler (armasm64)
|
||||
; http://msdn.microsoft.com/en-us/library/hh873190.aspx
|
||||
|
||||
AREA |.rdata|, DATA, READONLY
|
||||
EXPORT GetHFAReturnDouble
|
||||
EXPORT GetHFAReturnFloat
|
||||
EXPORT CallARM64Ret128
|
||||
EXPORT CallARM64RetInMemory
|
||||
EXPORT CallARM64Double
|
||||
EXPORT CallARM64Float
|
||||
EXPORT CallARM64
|
||||
|
||||
AREA |.text|, CODE, ALIGN=2
|
||||
|
||||
ALIGN 4
|
||||
GetHFAReturnDouble PROC
|
||||
adr x9, |populateDoubles|
|
||||
sub x9, x9, x1, lsr 1 ; x9 -= returnSize >> 1; (/2 because double is 2x instruction size)
|
||||
br x9
|
||||
|
||||
str d3, [x0, #0x18]
|
||||
str d2, [x0, #0x10]
|
||||
str d1, [x1]
|
||||
str d0, [x0]
|
||||
|populateDoubles|
|
||||
|
||||
ret
|
||||
ENDP ; GetHFAReturnDouble
|
||||
|
||||
ALIGN 4
|
||||
GetHFAReturnFloat PROC
|
||||
adr x9, |populateFloats|
|
||||
sub x9, x9, x2 // x9 -= returnSize; (already 4 bytes per return)
|
||||
br x9
|
||||
|
||||
str s3, [x1, #0x4]
|
||||
str s2, [x1]
|
||||
str s1, [x0, #0x4]
|
||||
str s0, [x0]
|
||||
|populateFloats|
|
||||
|
||||
ret
|
||||
ENDP ; GetHFAReturnFloat
|
||||
|
||||
|
||||
;[returnType] CallARM64[type](
|
||||
; const asQWORD *gpRegArgs, asQWORD numGPRegArgs,
|
||||
; const asQWORD *floatRegArgs, asQWORD numFloatRegArgs,
|
||||
; const asQWORD *stackArgs, asQWORD numStackArgs,
|
||||
; asFUNCTION_t func
|
||||
;)
|
||||
ALIGN 4
|
||||
CallARM64Double PROC
|
||||
stp fp, lr, [sp,#-0x10]!
|
||||
bl CallARM64
|
||||
ldp fp, lr, [sp,#-0x10]!
|
||||
ret
|
||||
ENDP ; CallARM64Double
|
||||
|
||||
ALIGN 4
|
||||
CallARM64Float PROC
|
||||
stp fp, lr, [sp,#-0x10]!
|
||||
bl CallARM64
|
||||
ldp fp, lr, [sp,#-0x10]!
|
||||
ret
|
||||
ENDP ; CallARM64Float
|
||||
|
||||
ALIGN 4
|
||||
CallARM64 PROC
|
||||
stp fp, lr, [sp,#-0x20]!
|
||||
str x20, [sp,#0x10]
|
||||
|
||||
mov x20, #0;
|
||||
|
||||
cbz x5, |stackArgsLoopEnd|
|
||||
|
||||
; Align count to 2, then multiply by 8, resulting in a size aligned to 16
|
||||
add x20, x5, #1
|
||||
lsl x20, x20, #3
|
||||
and x20, x20, #-0x10
|
||||
; Multiply count by 8
|
||||
lsl x10, x5, #3
|
||||
sub sp, sp, x20
|
||||
|stackArgsLoopStart|
|
||||
ldp x9,x11, [x4],#16
|
||||
stp x9,x11, [sp],#16
|
||||
subs x10, x10, #16
|
||||
bgt |stackArgsLoopStart|
|
||||
|stackArgsLoopEnd|
|
||||
|
||||
; Calculate amount to jump forward, avoiding pointless instructions
|
||||
adr x9, |populateFloatRegisterArgsEnd|
|
||||
sub x9, x9, x3, lsl 2 ; x9 -= numFloatRegArgs * 4
|
||||
br x9
|
||||
|
||||
ldr d7, [x2, #0x38]
|
||||
ldr d6, [x2, #0x30]
|
||||
ldr d5, [x2, #0x28]
|
||||
ldr d4, [x2, #0x20]
|
||||
ldr d3, [x2, #0x18]
|
||||
ldr d2, [x2, #0x10]
|
||||
ldr d1, [x2, #0x08]
|
||||
ldr d0, [x2]
|
||||
|populateFloatRegisterArgsEnd|
|
||||
|
||||
mov x15, x6
|
||||
; Calculate amount to jump forward, avoiding pointless instructions
|
||||
adr x9, |populateGPRegisterArgsEnd|
|
||||
sub x9, x9, x1, lsl 2 ; x9 -= numGPRegArgs * 4
|
||||
br x9
|
||||
|
||||
ldr x7, [x0, #0x38]
|
||||
ldr x6, [x0, #0x30]
|
||||
ldr x5, [x0, #0x28]
|
||||
ldr x4, [x0, #0x20]
|
||||
ldr x3, [x0, #0x18]
|
||||
ldr x2, [x0, #0x10]
|
||||
ldr x1, [x0, #0x08]
|
||||
ldr x0, [x0]
|
||||
|populateGPRegisterArgsEnd|
|
||||
|
||||
; Actually call function
|
||||
sub sp, sp, x20
|
||||
blr x15
|
||||
add sp, sp, x20
|
||||
|
||||
ldr x20, [sp,#0x10]
|
||||
ldp fp, lr, [sp],#0x20
|
||||
|
||||
ret
|
||||
ENDP ; CallARM64
|
||||
|
||||
ALIGN 4
|
||||
CallARM64Ret128 PROC
|
||||
stp fp, lr, [sp,#-0x20]!
|
||||
str x20, [sp,#0x10]
|
||||
mov fp, sp
|
||||
|
||||
mov x20, x6
|
||||
mov x6, x7
|
||||
mov x7, #0
|
||||
bl CallARM64
|
||||
|
||||
str x1, [x20]
|
||||
|
||||
ldr x20, [sp,#0x10]
|
||||
ldp fp, lr, [sp],#0x20
|
||||
|
||||
ret ; CallARM64Ret128
|
||||
|
||||
ALIGN 4
|
||||
CallARM64RetInMemory PROC
|
||||
stp fp, lr, [sp,#-0x10]!
|
||||
mov fp, sp
|
||||
|
||||
mov x8, x6
|
||||
mov x6, x7
|
||||
mov x7, #0
|
||||
bl CallARM64
|
||||
|
||||
mov x0, x8
|
||||
|
||||
ldp fp, lr, [sp],#0x10
|
||||
|
||||
ret ; CallARM64RetInMemory
|
||||
|
||||
END
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2016 Andreas Jonsson
|
||||
Copyright (c) 2003-2020 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
|
@ -43,7 +43,7 @@
|
|||
|
||||
#if defined(__arm__) || defined(__ARM__) || defined(I3D_ARCH_ARM)
|
||||
|
||||
#if !defined(__linux__) || defined(__ANDROID__) || defined(ANDROID) || defined(__SOFTFP__)
|
||||
#if !defined(__linux__) || defined(__ANDROID__) || defined(ANDROID) || defined(__SOFTFP__) || defined(__ARM_PCS)
|
||||
|
||||
/* iOS, Android, Marmalade, and Linux with soft-float ABI goes here */
|
||||
|
||||
|
@ -287,7 +287,7 @@ nomoreargsarmFuncR0R1:
|
|||
ldmia sp!, {r4-r8, pc}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------*/
|
||||
#elif defined(__linux__) && !defined(__SOFTFP__)
|
||||
#elif defined(__linux__) && !defined(__SOFTFP__) && !defined(__ARM_PCS)
|
||||
|
||||
/* The Linux with hard-float ABI code goes here */
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2019 Andreas Jonsson
|
||||
Copyright (c) 2003-2020 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
|
@ -102,6 +102,10 @@ asCCompiler::~asCCompiler()
|
|||
for (asUINT n = 0; n < usedStringConstants.GetLength(); n++)
|
||||
engine->stringFactory->ReleaseStringConstant(usedStringConstants[n]);
|
||||
usedStringConstants.SetLength(0);
|
||||
|
||||
// Clean up the temporary script nodes that were allocated during compilation
|
||||
for (asUINT n = 0; n < nodesToFreeUponComplete.GetLength(); n++)
|
||||
nodesToFreeUponComplete[n]->Destroy(engine);
|
||||
}
|
||||
|
||||
void asCCompiler::Reset(asCBuilder *in_builder, asCScriptCode *in_script, asCScriptFunction *in_outFunc)
|
||||
|
@ -352,7 +356,9 @@ int asCCompiler::SetupParametersAndReturnVariable(asCArray<asCString> ¶meter
|
|||
|
||||
// Is the return type allowed?
|
||||
if( returnType != asCDataType::CreatePrimitive(ttVoid, false) &&
|
||||
!returnType.CanBeInstantiated() )
|
||||
!returnType.CanBeInstantiated() &&
|
||||
!returnType.IsReference() &&
|
||||
!returnType.IsObjectHandle() )
|
||||
{
|
||||
// TODO: Hasn't this been validated by the builder already?
|
||||
asCString str;
|
||||
|
@ -431,6 +437,7 @@ void asCCompiler::CompileMemberInitialization(asCByteCode *bc, bool onlyDefaults
|
|||
asCObjectProperty *prop = outFunc->objectType->properties[n];
|
||||
|
||||
// Check if the property has an initialization expression
|
||||
asCParser parser(builder);
|
||||
asCScriptNode *declNode = 0;
|
||||
asCScriptNode *initNode = 0;
|
||||
asCScriptCode *initScript = 0;
|
||||
|
@ -466,7 +473,6 @@ void asCCompiler::CompileMemberInitialization(asCByteCode *bc, bool onlyDefaults
|
|||
initScript = script;
|
||||
#else
|
||||
// Re-parse the initialization expression as the parser now knows the types, which it didn't earlier
|
||||
asCParser parser(builder);
|
||||
int r = parser.ParseVarInit(initScript, initNode);
|
||||
if( r < 0 )
|
||||
continue;
|
||||
|
@ -2322,6 +2328,12 @@ int asCCompiler::CompileDefaultAndNamedArgs(asCScriptNode *node, asCArray<asCExp
|
|||
}
|
||||
|
||||
MergeExprBytecodeAndType(args[n], &expr);
|
||||
if (args[n]->exprNode)
|
||||
{
|
||||
// Disconnect the node from the parser, and tell the compiler to free it when complete
|
||||
args[n]->exprNode->DisconnectParent();
|
||||
nodesToFreeUponComplete.PushLast(args[n]->exprNode);
|
||||
}
|
||||
}
|
||||
|
||||
reservedVariables.SetLength(prevReservedVars);
|
||||
|
@ -2655,6 +2667,8 @@ bool asCCompiler::CompileAutoType(asCDataType &type, asCExprContext &compiledCtx
|
|||
// Handle const qualifier on auto
|
||||
if (type.IsReadOnly())
|
||||
newType.MakeReadOnly(true);
|
||||
else if (type.IsHandleToConst())
|
||||
newType.MakeHandleToConst(true);
|
||||
else if (newType.IsPrimitive())
|
||||
newType.MakeReadOnly(false);
|
||||
|
||||
|
@ -9253,7 +9267,7 @@ asCCompiler::SYMBOLTYPE asCCompiler::SymbolLookupMember(const asCString &name, a
|
|||
{
|
||||
asCScriptFunction *f = engine->scriptFunctions[ot->methods[n]];
|
||||
if (f->name == name &&
|
||||
(builder->module->accessMask & f->accessMask))
|
||||
(builder->module->m_accessMask & f->accessMask))
|
||||
{
|
||||
outResult->type.dataType.SetTypeInfo(objType);
|
||||
return SL_CLASSMETHOD;
|
||||
|
@ -9835,7 +9849,7 @@ int asCCompiler::CompileVariableAccess(const asCString &name, const asCString &s
|
|||
{
|
||||
asCScriptFunction *f = engine->scriptFunctions[ot->methods[n]];
|
||||
if (f->name == name &&
|
||||
(builder->module->accessMask & f->accessMask))
|
||||
(builder->module->m_accessMask & f->accessMask))
|
||||
{
|
||||
func = f;
|
||||
break;
|
||||
|
@ -10901,7 +10915,7 @@ int asCCompiler::CompileConstructCall(asCScriptNode *node, asCExprContext *ctx)
|
|||
|
||||
// It is possible that the name is really a constructor
|
||||
asCDataType dt;
|
||||
dt = builder->CreateDataTypeFromNode(node->firstChild, script, outFunc->nameSpace);
|
||||
dt = builder->CreateDataTypeFromNode(node->firstChild, script, outFunc->nameSpace, false, outFunc->objectType);
|
||||
if( dt.IsPrimitive() )
|
||||
{
|
||||
// This is a cast to a primitive type
|
||||
|
@ -10965,6 +10979,10 @@ int asCCompiler::CompileConstructCall(asCScriptNode *node, asCExprContext *ctx)
|
|||
conv.Copy(args[0]);
|
||||
asUINT cost = ImplicitConversion(&conv, dt, node->lastChild, asIC_EXPLICIT_VAL_CAST, false);
|
||||
|
||||
// Clean the property_arg in the temporary copy so
|
||||
// it isn't deleted when conv goes out of scope
|
||||
conv.property_arg = 0;
|
||||
|
||||
// Don't use this if the cost is 0 because it would mean that nothing
|
||||
// is done and the script wants a new value to be constructed
|
||||
if( conv.type.dataType.IsEqualExceptRef(dt) && cost > 0 )
|
||||
|
@ -11409,7 +11427,7 @@ int asCCompiler::CompileFunctionCall(asCScriptNode *node, asCExprContext *ctx, a
|
|||
if (symbolType == SL_CLASSTYPE || symbolType == SL_GLOBALTYPE)
|
||||
{
|
||||
bool isValid = false;
|
||||
asCDataType dt = builder->CreateDataTypeFromNode(node->firstChild, script, outFunc->nameSpace, false, 0, false, &isValid);
|
||||
asCDataType dt = builder->CreateDataTypeFromNode(node->firstChild, script, outFunc->nameSpace, false, outFunc->objectType, false, &isValid);
|
||||
if (isValid)
|
||||
return CompileConstructCall(node, ctx);
|
||||
}
|
||||
|
@ -13601,7 +13619,7 @@ int asCCompiler::CompileOverloadedDualOperator2(asCScriptNode *node, const char
|
|||
(!isConst || func->IsReadOnly()) )
|
||||
{
|
||||
// Make sure the method is accessible by the module
|
||||
if( builder->module->accessMask & func->accessMask )
|
||||
if( builder->module->m_accessMask & func->accessMask )
|
||||
{
|
||||
funcs.PushLast(func->id);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2019 Andreas Jonsson
|
||||
Copyright (c) 2003-2020 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
|
@ -424,6 +424,9 @@ protected:
|
|||
// so they can be released upon completion, whether the compilation was successful or not.
|
||||
asCArray<void*> usedStringConstants;
|
||||
|
||||
// This array holds the nodes that have been allocated temporarily
|
||||
asCArray<asCScriptNode*> nodesToFreeUponComplete;
|
||||
|
||||
bool isCompilingDefaultArg;
|
||||
bool isProcessingDeferredParams;
|
||||
int noCodeOutput;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2019 Andreas Jonsson
|
||||
Copyright (c) 2003-2020 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
|
@ -177,6 +177,14 @@
|
|||
// Oracle Solaris Studio (previously known as Sun CC compiler)
|
||||
// __SUNPRO_CC is defined
|
||||
|
||||
// Local (or Little) C Compiler
|
||||
// __LCC__ is defined
|
||||
// __e2k__ is not defined
|
||||
|
||||
// MCST eLbrus C Compiler
|
||||
// __LCC__ is defined
|
||||
// __e2k__ is defined
|
||||
|
||||
|
||||
|
||||
//
|
||||
|
@ -208,6 +216,9 @@
|
|||
// AS_ARM
|
||||
// Use assembler code for the ARM CPU family
|
||||
|
||||
// AS_ARM64
|
||||
// Use assembler code for the ARM64/AArch64 CPU family
|
||||
|
||||
// AS_SOFTFP
|
||||
// Use to tell compiler that ARM soft-float ABI
|
||||
// should be used instead of ARM hard-float ABI
|
||||
|
@ -227,6 +238,10 @@
|
|||
// AS_SPARC
|
||||
// Define this for SPARC CPU family
|
||||
|
||||
// AS_E2K
|
||||
// Define this for MCST Elbrus 2000 CPU family
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
|
@ -359,6 +374,14 @@
|
|||
#define AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
|
||||
|
||||
// Emscripten compiler toolchain
|
||||
// ref: https://emscripten.org/
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
#define AS_MAX_PORTABILITY
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// Embarcadero C++Builder
|
||||
#if defined(__BORLANDC__)
|
||||
#ifndef _Windows
|
||||
|
@ -482,7 +505,7 @@
|
|||
#define AS_CALLEE_DESTROY_OBJ_BY_VAL
|
||||
#define AS_LARGE_OBJS_PASSED_BY_REF
|
||||
#define AS_LARGE_OBJ_MIN_SIZE 3
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_CONSTRUCTOR | asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_ASSIGNMENT | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_CONSTRUCTOR | asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_ASSIGNMENT | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY | asOBJ_APP_CLASS_MORE_CONSTRUCTORS)
|
||||
#define COMPLEX_MASK (asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
|
||||
#endif
|
||||
#endif
|
||||
|
@ -502,12 +525,18 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(_M_ARM64)
|
||||
#define AS_ARM64
|
||||
|
||||
// TODO: MORE HERE
|
||||
#endif
|
||||
|
||||
#ifndef COMPLEX_MASK
|
||||
#define COMPLEX_MASK (asOBJ_APP_ARRAY)
|
||||
#endif
|
||||
|
||||
#ifndef COMPLEX_RETURN_MASK
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_CONSTRUCTOR | asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_ASSIGNMENT | asOBJ_APP_ARRAY)
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_CONSTRUCTOR | asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_ASSIGNMENT | asOBJ_APP_ARRAY | asOBJ_APP_CLASS_MORE_CONSTRUCTORS)
|
||||
#endif
|
||||
|
||||
#define UNREACHABLE_RETURN
|
||||
|
@ -864,7 +893,7 @@
|
|||
#elif defined(__ARMEL__) || defined(__arm__) || defined(__aarch64__) || defined(__AARCH64EL__)
|
||||
// arm
|
||||
|
||||
// The assembler code currently doesn't support arm v4, nor 64bit (v8)
|
||||
// The assembler code currently doesn't support arm v4
|
||||
#if !defined(__ARM_ARCH_4__) && !defined(__ARM_ARCH_4T__) && !defined(__LP64__)
|
||||
#define AS_ARM
|
||||
|
||||
|
@ -894,13 +923,35 @@
|
|||
#endif
|
||||
|
||||
// Verify if soft-float or hard-float ABI is used
|
||||
#if defined(__SOFTFP__) && __SOFTFP__ == 1
|
||||
#if (defined(__SOFTFP__) && __SOFTFP__ == 1) || defined(__ARM_PCS)
|
||||
// -ffloat-abi=softfp or -ffloat-abi=soft
|
||||
#define AS_SOFTFP
|
||||
#endif
|
||||
|
||||
// Tested with both hard float and soft float abi
|
||||
#undef AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
#elif defined(__LP64__) || defined(__aarch64__)
|
||||
#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
|
||||
|
||||
#elif defined(__mips__)
|
||||
|
@ -932,6 +983,17 @@
|
|||
// although use 64bit PPC only uses 32bit pointers.
|
||||
// TODO: Add support for native calling conventions on Linux with PPC 64bit
|
||||
#define AS_MAX_PORTABILITY
|
||||
#elif defined(__e2k__)
|
||||
// 64bit MCST Elbrus 2000
|
||||
// ref: https://en.wikipedia.org/wiki/Elbrus_2000
|
||||
#define AS_E2K
|
||||
// AngelScript currently doesn't support native calling
|
||||
// for MCST Elbrus 2000 processor so it's necessary to turn on
|
||||
// portability mode
|
||||
#define AS_MAX_PORTABILITY
|
||||
// STDCALL is not available on 64bit Linux
|
||||
#undef STDCALL
|
||||
#define STDCALL
|
||||
#else
|
||||
#define AS_MAX_PORTABILITY
|
||||
#endif
|
||||
|
@ -1085,25 +1147,28 @@
|
|||
// Haiku OS
|
||||
#elif __HAIKU__
|
||||
#define AS_HAIKU
|
||||
// Only x86-32 is currently supported by Haiku, but they do plan to support
|
||||
// x86-64 and PowerPC in the future, so should go ahead and check the platform
|
||||
// for future compatibility
|
||||
#if (defined(i386) || defined(__i386) || defined(__i386__)) && !defined(__LP64__)
|
||||
#define AS_X86
|
||||
#define THISCALL_PASS_OBJECT_POINTER_ON_THE_STACK
|
||||
#define THISCALL_RETURN_SIMPLE_IN_MEMORY
|
||||
#define CDECL_RETURN_SIMPLE_IN_MEMORY
|
||||
#define STDCALL_RETURN_SIMPLE_IN_MEMORY
|
||||
#elif defined(__x86_64__)
|
||||
#define AS_X64_GCC
|
||||
#define HAS_128_BIT_PRIMITIVES
|
||||
#define SPLIT_OBJS_BY_MEMBER_TYPES
|
||||
#undef COMPLEX_MASK
|
||||
#define COMPLEX_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
|
||||
#undef COMPLEX_RETURN_MASK
|
||||
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
|
||||
#define AS_LARGE_OBJS_PASSED_BY_REF
|
||||
#define AS_LARGE_OBJ_MIN_SIZE 5
|
||||
#undef STDCALL
|
||||
#define STDCALL
|
||||
#else
|
||||
#define AS_MAX_PORTABILITY
|
||||
#endif
|
||||
|
||||
#define AS_POSIX_THREADS
|
||||
#if !( ( (__GNUC__ == 4) && (__GNUC_MINOR__ >= 1) || __GNUC__ > 4) )
|
||||
// Only with GCC 4.1 was the atomic instructions available
|
||||
#define AS_NO_ATOMIC
|
||||
#endif
|
||||
|
||||
// Illumos
|
||||
#elif defined(__sun)
|
||||
#if (defined(i386) || defined(__i386) || defined(__i386__)) && !defined(__LP64__)
|
||||
|
@ -1193,7 +1258,7 @@
|
|||
|
||||
// If there are no current support for native calling
|
||||
// conventions, then compile with AS_MAX_PORTABILITY
|
||||
#if (!defined(AS_X86) && !defined(AS_SH4) && !defined(AS_MIPS) && !defined(AS_PPC) && !defined(AS_PPC_64) && !defined(AS_XENON) && !defined(AS_X64_GCC) && !defined(AS_X64_MSVC) && !defined(AS_ARM) && !defined(AS_X64_MINGW))
|
||||
#if (!defined(AS_X86) && !defined(AS_SH4) && !defined(AS_MIPS) && !defined(AS_PPC) && !defined(AS_PPC_64) && !defined(AS_XENON) && !defined(AS_X64_GCC) && !defined(AS_X64_MSVC) && !defined(AS_ARM) && !defined(AS_ARM64) && !defined(AS_X64_MINGW))
|
||||
#ifndef AS_MAX_PORTABILITY
|
||||
#define AS_MAX_PORTABILITY
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2017 Andreas Jonsson
|
||||
Copyright (c) 2003-2020 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
|
@ -130,7 +130,6 @@ void asCConfigGroup::RemoveConfiguration(asCScriptEngine *engine, bool notUsed)
|
|||
{
|
||||
globalProps[n]->Release();
|
||||
|
||||
// TODO: global: Should compact the registeredGlobalProps array
|
||||
engine->registeredGlobalProps.Erase(index);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2019 Andreas Jonsson
|
||||
Copyright (c) 2003-2020 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
|
@ -4404,7 +4404,23 @@ void asCContext::ExecuteNext()
|
|||
|
||||
// Call the method
|
||||
m_callingSystemFunction = m_engine->scriptFunctions[i];
|
||||
void *ptr = m_engine->CallObjectMethodRetPtr(obj, arg, m_callingSystemFunction);
|
||||
void *ptr = 0;
|
||||
#ifdef AS_NO_EXCEPTIONS
|
||||
ptr = m_engine->CallObjectMethodRetPtr(obj, arg, m_callingSystemFunction);
|
||||
#else
|
||||
// This try/catch block is to catch potential exception that may
|
||||
// be thrown by the registered function.
|
||||
try
|
||||
{
|
||||
ptr = m_engine->CallObjectMethodRetPtr(obj, arg, m_callingSystemFunction);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// Convert the exception to a script exception so the VM can
|
||||
// properly report the error to the application and then clean up
|
||||
HandleAppException();
|
||||
}
|
||||
#endif
|
||||
m_callingSystemFunction = 0;
|
||||
*(asPWORD*)&m_regs.valueRegister = (asPWORD)ptr;
|
||||
}
|
||||
|
@ -4816,8 +4832,9 @@ void asCContext::DetermineLiveObjects(asCArray<int> &liveObjects, asUINT stackLe
|
|||
}
|
||||
}
|
||||
break;
|
||||
case asOBJ_VARDECL:
|
||||
break;
|
||||
case asOBJ_VARDECL: // A variable was declared
|
||||
// We don't really care about the variable declarations at this moment
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2016 Andreas Jonsson
|
||||
Copyright (c) 2003-2020 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
|
@ -38,7 +38,7 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
|
||||
#if !defined(__APPLE__) && !defined(__SNC__) && !defined(__ghs__) && !defined(__FreeBSD__) && !defined(__OpenBSD__)
|
||||
#if !defined(__APPLE__) && !defined(__SNC__) && !defined(__ghs__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__DragonFly__)
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
|
@ -241,6 +241,11 @@ void asCMemoryMgr::FreeScriptNode(void *ptr)
|
|||
scriptNodePool.Allocate(100, 0);
|
||||
|
||||
scriptNodePool.PushLast(ptr);
|
||||
|
||||
#ifdef AS_DEBUG
|
||||
// clear the memory to facilitate identification of use after free
|
||||
memset(ptr, 0xCDCDCDCD, sizeof(asCScriptNode));
|
||||
#endif
|
||||
|
||||
LEAVECRITICALSECTION(cs);
|
||||
}
|
||||
|
@ -249,6 +254,8 @@ void asCMemoryMgr::FreeScriptNode(void *ptr)
|
|||
|
||||
void *asCMemoryMgr::AllocByteInstruction()
|
||||
{
|
||||
// This doesn't need a critical section because, only one compilation is allowed at a time
|
||||
|
||||
if( byteInstructionPool.GetLength() )
|
||||
return byteInstructionPool.PopLast();
|
||||
|
||||
|
@ -266,6 +273,11 @@ void asCMemoryMgr::FreeByteInstruction(void *ptr)
|
|||
byteInstructionPool.Allocate(100, 0);
|
||||
|
||||
byteInstructionPool.PushLast(ptr);
|
||||
|
||||
#ifdef AS_DEBUG
|
||||
// clear the memory to facilitate identification of use after free
|
||||
memset(ptr, 0xCDCDCDCD, sizeof(asCByteInstruction));
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // AS_NO_COMPILER
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2019 Andreas Jonsson
|
||||
Copyright (c) 2003-2020 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
|
@ -182,6 +182,7 @@ public:
|
|||
|
||||
int CallInit(asIScriptContext *ctx);
|
||||
void CallExit();
|
||||
int InitGlobalProp(asCGlobalProperty *prop, asIScriptContext *ctx);
|
||||
|
||||
void JITCompile();
|
||||
|
||||
|
@ -194,47 +195,61 @@ public:
|
|||
|
||||
int GetNextImportedFunctionId();
|
||||
asCScriptFunction *GetImportedFunction(int funcId) const;
|
||||
asCTypeInfo *GetType(const char *type, asSNameSpace *ns);
|
||||
asCObjectType *GetObjectType(const char *type, asSNameSpace *ns);
|
||||
asCTypeInfo *GetType(const asCString &type, asSNameSpace *ns) const;
|
||||
asCObjectType *GetObjectType(const char *type, asSNameSpace *ns) const;
|
||||
asCGlobalProperty *AllocateGlobalProperty(const char *name, const asCDataType &dt, asSNameSpace *ns);
|
||||
void UninitializeGlobalProp(asCGlobalProperty *prop);
|
||||
|
||||
// Adds the class type to the module. The module assumes ownership of the reference without increasing it
|
||||
void AddClassType(asCObjectType*);
|
||||
// Adds the enum type to the module. The module assumes ownership of the reference without increasing it
|
||||
void AddEnumType(asCEnumType*);
|
||||
// Adds the typedef to the module. The module assumes ownership of the reference without increasing it
|
||||
void AddTypeDef(asCTypedefType*);
|
||||
// Adds the funcdef to the module. The module assumes ownership of the reference without increasing it
|
||||
void AddFuncDef(asCFuncdefType*);
|
||||
// Replaces an existing funcdef with another (used for shared funcdefs). Doesn't add or release refCounts
|
||||
void ReplaceFuncDef(asCFuncdefType *oldType, asCFuncdefType *newType);
|
||||
|
||||
asCString name;
|
||||
|
||||
asCScriptEngine *engine;
|
||||
asCBuilder *builder;
|
||||
asCArray<asPWORD> userData;
|
||||
asDWORD accessMask;
|
||||
asSNameSpace *defaultNamespace;
|
||||
asCString m_name;
|
||||
asCScriptEngine *m_engine;
|
||||
asCBuilder *m_builder;
|
||||
asCArray<asPWORD> m_userData;
|
||||
asDWORD m_accessMask;
|
||||
asSNameSpace *m_defaultNamespace;
|
||||
|
||||
// This array holds all functions, class members, factories, etc that were compiled with the module.
|
||||
// These references hold an internal reference to the function object.
|
||||
asCArray<asCScriptFunction *> scriptFunctions; // increases ref count
|
||||
asCArray<asCScriptFunction *> m_scriptFunctions; // increases ref count
|
||||
// This array holds global functions declared in the module. These references are not counted,
|
||||
// as the same pointer is always present in the scriptFunctions array too.
|
||||
asCSymbolTable<asCScriptFunction> globalFunctions; // doesn't increase ref count
|
||||
asCSymbolTable<asCScriptFunction> m_globalFunctions; // doesn't increase ref count
|
||||
// This array holds imported functions in the module.
|
||||
asCArray<sBindInfo *> bindInformations; // increases ref count
|
||||
asCArray<sBindInfo *> m_bindInformations; // increases ref count
|
||||
// This array holds template instance types created for the module's object types
|
||||
asCArray<asCObjectType*> templateInstances; // increases ref count
|
||||
asCArray<asCObjectType*> m_templateInstances; // increases ref count
|
||||
|
||||
// This array holds the global variables declared in the script
|
||||
asCSymbolTable<asCGlobalProperty> scriptGlobals; // increases ref count
|
||||
bool isGlobalVarInitialized;
|
||||
asCSymbolTable<asCGlobalProperty> m_scriptGlobals; // increases ref count
|
||||
bool m_isGlobalVarInitialized;
|
||||
|
||||
// This array holds class and interface types
|
||||
asCArray<asCObjectType*> classTypes; // increases ref count
|
||||
asCArray<asCObjectType*> m_classTypes; // increases ref count
|
||||
// This array holds enum types
|
||||
asCArray<asCEnumType*> enumTypes; // increases ref count
|
||||
asCArray<asCEnumType*> m_enumTypes; // increases ref count
|
||||
// This array holds typedefs
|
||||
asCArray<asCTypedefType*> typeDefs; // increases ref count
|
||||
asCArray<asCTypedefType*> m_typeDefs; // increases ref count
|
||||
// This array holds the funcdefs declared in the module
|
||||
asCArray<asCFuncdefType*> funcDefs; // increases ref count
|
||||
asCArray<asCFuncdefType*> m_funcDefs; // increases ref count
|
||||
|
||||
// This map contains all the types (also contained in the arrays above) for quick lookup
|
||||
// TODO: memory: Can we eliminate the arrays above?
|
||||
asCMap<asSNameSpaceNamePair, asCTypeInfo*> m_typeLookup; // doesn't increase ref count
|
||||
|
||||
// This array holds types that have been explicitly declared with 'external'
|
||||
asCArray<asCTypeInfo*> externalTypes; // doesn't increase ref count
|
||||
asCArray<asCTypeInfo*> m_externalTypes; // doesn't increase ref count
|
||||
// This array holds functions that have been explicitly declared with 'external'
|
||||
asCArray<asCScriptFunction*> externalFunctions; // doesn't increase ref count
|
||||
asCArray<asCScriptFunction*> m_externalFunctions; // doesn't increase ref count
|
||||
};
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2019 Andreas Jonsson
|
||||
Copyright (c) 2003-2020 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
|
@ -90,12 +90,12 @@ int asCReader::Read(bool *wasDebugInfoStripped)
|
|||
// Make sure none of the loaded functions attempt to release
|
||||
// references that have not yet been increased
|
||||
asUINT i;
|
||||
for( i = 0; i < module->scriptFunctions.GetLength(); i++ )
|
||||
if( !dontTranslate.MoveTo(0, module->scriptFunctions[i]) )
|
||||
if( module->scriptFunctions[i]->scriptData )
|
||||
module->scriptFunctions[i]->scriptData->byteCode.SetLength(0);
|
||||
for( i = 0; i < module->m_scriptFunctions.GetLength(); i++ )
|
||||
if( !dontTranslate.MoveTo(0, module->m_scriptFunctions[i]) )
|
||||
if( module->m_scriptFunctions[i]->scriptData )
|
||||
module->m_scriptFunctions[i]->scriptData->byteCode.SetLength(0);
|
||||
|
||||
asCSymbolTable<asCGlobalProperty>::iterator it = module->scriptGlobals.List();
|
||||
asCSymbolTable<asCGlobalProperty>::iterator it = module->m_scriptGlobals.List();
|
||||
for( ; it; it++ )
|
||||
if( (*it)->GetInitFunc() )
|
||||
if( (*it)->GetInitFunc()->scriptData )
|
||||
|
@ -156,7 +156,7 @@ int asCReader::ReadInner()
|
|||
|
||||
// Read enums
|
||||
count = ReadEncodedUInt();
|
||||
module->enumTypes.Allocate(count, false);
|
||||
module->m_enumTypes.Allocate(count, false);
|
||||
for( i = 0; i < count && !error; i++ )
|
||||
{
|
||||
asCEnumType *et = asNEW(asCEnumType)(engine);
|
||||
|
@ -216,10 +216,10 @@ int asCReader::ReadInner()
|
|||
// Set this module as the owner
|
||||
et->module = module;
|
||||
}
|
||||
module->enumTypes.PushLast(et);
|
||||
module->AddEnumType(et);
|
||||
|
||||
if (isExternal)
|
||||
module->externalTypes.PushLast(et);
|
||||
module->m_externalTypes.PushLast(et);
|
||||
|
||||
ReadTypeDeclaration(et, 2);
|
||||
}
|
||||
|
@ -229,7 +229,7 @@ int asCReader::ReadInner()
|
|||
// classTypes[]
|
||||
// First restore the structure names, then the properties
|
||||
count = ReadEncodedUInt();
|
||||
module->classTypes.Allocate(count, false);
|
||||
module->m_classTypes.Allocate(count, false);
|
||||
for( i = 0; i < count && !error; ++i )
|
||||
{
|
||||
asCObjectType *ot = asNEW(asCObjectType)(engine);
|
||||
|
@ -290,17 +290,17 @@ int asCReader::ReadInner()
|
|||
// Set this module as the owner
|
||||
ot->module = module;
|
||||
}
|
||||
module->classTypes.PushLast(ot);
|
||||
module->AddClassType(ot);
|
||||
|
||||
if (isExternal)
|
||||
module->externalTypes.PushLast(ot);
|
||||
module->m_externalTypes.PushLast(ot);
|
||||
}
|
||||
|
||||
if( error ) return asERROR;
|
||||
|
||||
// Read func defs
|
||||
count = ReadEncodedUInt();
|
||||
module->funcDefs.Allocate(count, false);
|
||||
module->m_funcDefs.Allocate(count, false);
|
||||
for( i = 0; i < count && !error; i++ )
|
||||
{
|
||||
bool isNew, isExternal;
|
||||
|
@ -312,7 +312,7 @@ int asCReader::ReadInner()
|
|||
asCFuncdefType *fdt = funcDef->funcdefType;
|
||||
fdt->module = module;
|
||||
|
||||
module->funcDefs.PushLast(fdt);
|
||||
module->AddFuncDef(fdt);
|
||||
engine->funcDefs.PushLast(fdt);
|
||||
|
||||
// TODO: clean up: This is also done by the builder. It should probably be moved to a method in the module
|
||||
|
@ -334,11 +334,11 @@ int asCReader::ReadInner()
|
|||
f2->funcdef->IsSignatureExceptNameEqual(funcDef) )
|
||||
{
|
||||
// Replace our funcdef for the existing one
|
||||
module->funcDefs[module->funcDefs.IndexOf(fdt)] = f2;
|
||||
module->ReplaceFuncDef(fdt, f2);
|
||||
f2->AddRefInternal();
|
||||
|
||||
if (isExternal)
|
||||
module->externalTypes.PushLast(f2);
|
||||
module->m_externalTypes.PushLast(f2);
|
||||
|
||||
engine->funcDefs.RemoveValue(fdt);
|
||||
|
||||
|
@ -378,31 +378,31 @@ int asCReader::ReadInner()
|
|||
}
|
||||
|
||||
// Read interface methods
|
||||
for( i = 0; i < module->classTypes.GetLength() && !error; i++ )
|
||||
for( i = 0; i < module->m_classTypes.GetLength() && !error; i++ )
|
||||
{
|
||||
if( module->classTypes[i]->IsInterface() )
|
||||
ReadTypeDeclaration(module->classTypes[i], 2);
|
||||
if( module->m_classTypes[i]->IsInterface() )
|
||||
ReadTypeDeclaration(module->m_classTypes[i], 2);
|
||||
}
|
||||
|
||||
// Read class methods and behaviours
|
||||
for( i = 0; i < module->classTypes.GetLength() && !error; ++i )
|
||||
for( i = 0; i < module->m_classTypes.GetLength() && !error; ++i )
|
||||
{
|
||||
if( !module->classTypes[i]->IsInterface() )
|
||||
ReadTypeDeclaration(module->classTypes[i], 2);
|
||||
if( !module->m_classTypes[i]->IsInterface() )
|
||||
ReadTypeDeclaration(module->m_classTypes[i], 2);
|
||||
}
|
||||
|
||||
// Read class properties
|
||||
for( i = 0; i < module->classTypes.GetLength() && !error; ++i )
|
||||
for( i = 0; i < module->m_classTypes.GetLength() && !error; ++i )
|
||||
{
|
||||
if( !module->classTypes[i]->IsInterface() )
|
||||
ReadTypeDeclaration(module->classTypes[i], 3);
|
||||
if( !module->m_classTypes[i]->IsInterface() )
|
||||
ReadTypeDeclaration(module->m_classTypes[i], 3);
|
||||
}
|
||||
|
||||
if( error ) return asERROR;
|
||||
|
||||
// Read typedefs
|
||||
count = ReadEncodedUInt();
|
||||
module->typeDefs.Allocate(count, false);
|
||||
module->m_typeDefs.Allocate(count, false);
|
||||
for( i = 0; i < count && !error; i++ )
|
||||
{
|
||||
asCTypedefType *td = asNEW(asCTypedefType)(engine);
|
||||
|
@ -415,7 +415,7 @@ int asCReader::ReadInner()
|
|||
bool isExternal = false;
|
||||
ReadTypeDeclaration(td, 1, &isExternal);
|
||||
td->module = module;
|
||||
module->typeDefs.PushLast(td);
|
||||
module->AddTypeDef(td);
|
||||
ReadTypeDeclaration(td, 2);
|
||||
}
|
||||
|
||||
|
@ -428,7 +428,7 @@ int asCReader::ReadInner()
|
|||
engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, TXT_GLOBAL_VARS_NOT_ALLOWED);
|
||||
Error(TXT_INVALID_BYTECODE_d);
|
||||
}
|
||||
module->scriptGlobals.Allocate(count, false);
|
||||
module->m_scriptGlobals.Allocate(count, false);
|
||||
for( i = 0; i < count && !error; ++i )
|
||||
{
|
||||
ReadGlobalProperty();
|
||||
|
@ -438,7 +438,7 @@ int asCReader::ReadInner()
|
|||
count = ReadEncodedUInt();
|
||||
for( i = 0; i < count && !error; ++i )
|
||||
{
|
||||
size_t len = module->scriptFunctions.GetLength();
|
||||
size_t len = module->m_scriptFunctions.GetLength();
|
||||
bool isNew, isExternal;
|
||||
func = ReadFunction(isNew, true, true, true, &isExternal);
|
||||
if( func == 0 )
|
||||
|
@ -448,7 +448,7 @@ int asCReader::ReadInner()
|
|||
}
|
||||
|
||||
// Is the function shared and was it created now?
|
||||
if( func->IsShared() && len != module->scriptFunctions.GetLength() )
|
||||
if( func->IsShared() && len != module->m_scriptFunctions.GetLength() )
|
||||
{
|
||||
// If the function already existed in another module, then
|
||||
// we need to replace it with previously existing one
|
||||
|
@ -462,7 +462,7 @@ int asCReader::ReadInner()
|
|||
realFunc->IsSignatureEqual(func) )
|
||||
{
|
||||
// Replace the recently created function with the pre-existing function
|
||||
module->scriptFunctions[module->scriptFunctions.GetLength()-1] = realFunc;
|
||||
module->m_scriptFunctions[module->m_scriptFunctions.GetLength()-1] = realFunc;
|
||||
realFunc->AddRefInternal();
|
||||
savedFunctions[savedFunctions.GetLength()-1] = realFunc;
|
||||
engine->RemoveScriptFunction(func);
|
||||
|
@ -471,7 +471,7 @@ int asCReader::ReadInner()
|
|||
dontTranslate.Insert(realFunc, true);
|
||||
|
||||
if (isExternal)
|
||||
module->externalFunctions.PushLast(realFunc);
|
||||
module->m_externalFunctions.PushLast(realFunc);
|
||||
|
||||
// Release the function, but make sure nothing else is released
|
||||
func->id = 0;
|
||||
|
@ -507,7 +507,7 @@ int asCReader::ReadInner()
|
|||
// we're just re-reading the references to know which goes into the globalFunctions array
|
||||
asASSERT( !isNew );
|
||||
|
||||
module->globalFunctions.Put(func);
|
||||
module->m_globalFunctions.Put(func);
|
||||
}
|
||||
else
|
||||
Error(TXT_INVALID_BYTECODE_d);
|
||||
|
@ -517,7 +517,7 @@ int asCReader::ReadInner()
|
|||
|
||||
// bindInformations[]
|
||||
count = ReadEncodedUInt();
|
||||
module->bindInformations.Allocate(count, false);
|
||||
module->m_bindInformations.Allocate(count, false);
|
||||
for( i = 0; i < count && !error; ++i )
|
||||
{
|
||||
sBindInfo *info = asNEW(sBindInfo);
|
||||
|
@ -548,7 +548,7 @@ int asCReader::ReadInner()
|
|||
}
|
||||
ReadString(&info->importFromModule);
|
||||
info->boundFunctionId = -1;
|
||||
module->bindInformations.PushLast(info);
|
||||
module->m_bindInformations.PushLast(info);
|
||||
}
|
||||
|
||||
if( error ) return asERROR;
|
||||
|
@ -622,11 +622,11 @@ int asCReader::ReadInner()
|
|||
|
||||
// Update the loaded bytecode to point to the correct types, property offsets,
|
||||
// function ids, etc. This is basically a linking stage.
|
||||
for( i = 0; i < module->scriptFunctions.GetLength() && !error; i++ )
|
||||
if( module->scriptFunctions[i]->funcType == asFUNC_SCRIPT )
|
||||
TranslateFunction(module->scriptFunctions[i]);
|
||||
for( i = 0; i < module->m_scriptFunctions.GetLength() && !error; i++ )
|
||||
if( module->m_scriptFunctions[i]->funcType == asFUNC_SCRIPT )
|
||||
TranslateFunction(module->m_scriptFunctions[i]);
|
||||
|
||||
asCSymbolTable<asCGlobalProperty>::iterator globIt = module->scriptGlobals.List();
|
||||
asCSymbolTable<asCGlobalProperty>::iterator globIt = module->m_scriptGlobals.List();
|
||||
while( globIt && !error )
|
||||
{
|
||||
asCScriptFunction *initFunc = (*globIt)->GetInitFunc();
|
||||
|
@ -638,11 +638,11 @@ int asCReader::ReadInner()
|
|||
if( error ) return asERROR;
|
||||
|
||||
// Add references for all functions (except for the pre-existing shared code)
|
||||
for( i = 0; i < module->scriptFunctions.GetLength(); i++ )
|
||||
if( !dontTranslate.MoveTo(0, module->scriptFunctions[i]) )
|
||||
module->scriptFunctions[i]->AddReferences();
|
||||
for( i = 0; i < module->m_scriptFunctions.GetLength(); i++ )
|
||||
if( !dontTranslate.MoveTo(0, module->m_scriptFunctions[i]) )
|
||||
module->m_scriptFunctions[i]->AddReferences();
|
||||
|
||||
globIt = module->scriptGlobals.List();
|
||||
globIt = module->m_scriptGlobals.List();
|
||||
while( globIt )
|
||||
{
|
||||
asCScriptFunction *initFunc = (*globIt)->GetInitFunc();
|
||||
|
@ -721,9 +721,9 @@ void asCReader::ReadUsedFunctions()
|
|||
{
|
||||
if( func.funcType == asFUNC_IMPORTED )
|
||||
{
|
||||
for( asUINT i = 0; i < module->bindInformations.GetLength(); i++ )
|
||||
for( asUINT i = 0; i < module->m_bindInformations.GetLength(); i++ )
|
||||
{
|
||||
asCScriptFunction *f = module->bindInformations[i]->importedFunctionSignature;
|
||||
asCScriptFunction *f = module->m_bindInformations[i]->importedFunctionSignature;
|
||||
if( func.objectType != f->objectType ||
|
||||
func.funcType != f->funcType ||
|
||||
func.nameSpace != f->nameSpace ||
|
||||
|
@ -736,7 +736,7 @@ void asCReader::ReadUsedFunctions()
|
|||
}
|
||||
else if( func.funcType == asFUNC_FUNCDEF )
|
||||
{
|
||||
const asCArray<asCFuncdefType *> &funcs = module->funcDefs;
|
||||
const asCArray<asCFuncdefType *> &funcs = module->m_funcDefs;
|
||||
for( asUINT i = 0; i < funcs.GetLength(); i++ )
|
||||
{
|
||||
asCScriptFunction *f = funcs[i]->funcdef;
|
||||
|
@ -757,9 +757,9 @@ void asCReader::ReadUsedFunctions()
|
|||
// TODO: optimize: Global functions should be searched for in module->globalFunctions
|
||||
// TODO: optimize: funcdefs should be searched for in module->funcDefs
|
||||
// TODO: optimize: object methods should be searched for directly in the object type
|
||||
for( asUINT i = 0; i < module->scriptFunctions.GetLength(); i++ )
|
||||
for( asUINT i = 0; i < module->m_scriptFunctions.GetLength(); i++ )
|
||||
{
|
||||
asCScriptFunction *f = module->scriptFunctions[i];
|
||||
asCScriptFunction *f = module->m_scriptFunctions[i];
|
||||
if( func.objectType != f->objectType ||
|
||||
func.funcType != f->funcType ||
|
||||
func.nameSpace != f->nameSpace ||
|
||||
|
@ -922,17 +922,6 @@ void asCReader::ReadUsedFunctions()
|
|||
usedFunctions[n] = f;
|
||||
}
|
||||
}
|
||||
else if( func.name == "$beh4" )
|
||||
{
|
||||
// This is a list factory, so check the return type's list factory
|
||||
asCObjectType *objType = CastToObjectType(func.returnType.GetTypeInfo());
|
||||
if( objType )
|
||||
{
|
||||
asCScriptFunction *f = engine->scriptFunctions[objType->beh.listFactory];
|
||||
if( f && func.IsSignatureExceptNameAndObjectTypeEqual(f) )
|
||||
usedFunctions[n] = f;
|
||||
}
|
||||
}
|
||||
else if( func.name == "$dlgte" )
|
||||
{
|
||||
// This is the delegate factory
|
||||
|
@ -940,6 +929,11 @@ void asCReader::ReadUsedFunctions()
|
|||
asASSERT( f && func.IsSignatureEqual(f) );
|
||||
usedFunctions[n] = f;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Must match one of the above cases
|
||||
asASSERT(false);
|
||||
}
|
||||
}
|
||||
else if( func.objectType == 0 )
|
||||
{
|
||||
|
@ -1205,7 +1199,7 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
|
|||
if( func->funcType == asFUNC_SCRIPT )
|
||||
{
|
||||
// Skip this for external shared entities
|
||||
if (module->externalTypes.IndexOf(func->objectType) >= 0)
|
||||
if (module->m_externalTypes.IndexOf(func->objectType) >= 0)
|
||||
{
|
||||
// Replace with the real function from the existing entity
|
||||
isNew = false;
|
||||
|
@ -1429,10 +1423,110 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
|
|||
fdt->parentClass = parentClass;
|
||||
}
|
||||
|
||||
// Methods loaded for shared objects, owned by other modules should not be created as new functions
|
||||
if( func->objectType && func->objectType->module != module )
|
||||
{
|
||||
// Return the real function from the object
|
||||
asCScriptFunction *realFunc = 0;
|
||||
bool found = false;
|
||||
if( func->funcType == asFUNC_SCRIPT )
|
||||
{
|
||||
realFunc = engine->scriptFunctions[func->objectType->beh.destruct];
|
||||
if( realFunc && realFunc->funcType != asFUNC_VIRTUAL && func->IsSignatureEqual(realFunc) )
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
for( asUINT n = 0; !found && n < func->objectType->beh.constructors.GetLength(); n++ )
|
||||
{
|
||||
realFunc = engine->scriptFunctions[func->objectType->beh.constructors[n]];
|
||||
if( realFunc && realFunc->funcType != asFUNC_VIRTUAL && func->IsSignatureEqual(realFunc) )
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for( asUINT n = 0; !found && n < func->objectType->beh.factories.GetLength(); n++ )
|
||||
{
|
||||
realFunc = engine->scriptFunctions[func->objectType->beh.factories[n]];
|
||||
if( realFunc && realFunc->funcType != asFUNC_VIRTUAL && func->IsSignatureEqual(realFunc) )
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for( asUINT n = 0; !found && n < func->objectType->methods.GetLength(); n++ )
|
||||
{
|
||||
realFunc = engine->scriptFunctions[func->objectType->methods[n]];
|
||||
if( realFunc && realFunc->funcType == func->funcType && func->IsSignatureEqual(realFunc) )
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for( asUINT n = 0; !found && n < func->objectType->virtualFunctionTable.GetLength(); n++ )
|
||||
{
|
||||
realFunc = func->objectType->virtualFunctionTable[n];
|
||||
if( realFunc && realFunc->funcType == func->funcType && func->IsSignatureEqual(realFunc) )
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( func->funcType == asFUNC_VIRTUAL || func->funcType == asFUNC_INTERFACE )
|
||||
{
|
||||
// If the loaded function is a virtual function, then look for the identical virtual function in the methods array
|
||||
for( asUINT n = 0; n < func->objectType->methods.GetLength(); n++ )
|
||||
{
|
||||
realFunc = engine->scriptFunctions[func->objectType->methods[n]];
|
||||
if( realFunc && realFunc->funcType == func->funcType && func->IsSignatureEqual(realFunc) )
|
||||
{
|
||||
asASSERT( func->vfTableIdx == realFunc->vfTableIdx );
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( found )
|
||||
{
|
||||
// as this is an existing function it shouldn't be translated as if just loaded
|
||||
dontTranslate.Insert(realFunc, true);
|
||||
|
||||
// update the saved functions for future references
|
||||
savedFunctions[savedFunctions.GetLength() - 1] = realFunc;
|
||||
|
||||
if( realFunc->funcType == asFUNC_VIRTUAL && addToModule )
|
||||
{
|
||||
// Virtual methods must be added to the module's script functions array,
|
||||
// even if they are not owned by the module
|
||||
module->m_scriptFunctions.PushLast(realFunc);
|
||||
realFunc->AddRefInternal();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
asCString str;
|
||||
str.Format(TXT_SHARED_s_DOESNT_MATCH_ORIGINAL, func->objectType->GetName());
|
||||
engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
|
||||
|
||||
Error(TXT_INVALID_BYTECODE_d);
|
||||
savedFunctions.PopLast();
|
||||
realFunc = 0;
|
||||
}
|
||||
|
||||
// Destroy the newly created function instance since it has been replaced by an existing function
|
||||
isNew = false;
|
||||
func->DestroyHalfCreated();
|
||||
|
||||
// As it is an existing function it shouldn't be added to the module or the engine
|
||||
return realFunc;
|
||||
}
|
||||
|
||||
if( addToModule )
|
||||
{
|
||||
// The refCount is already 1
|
||||
module->scriptFunctions.PushLast(func);
|
||||
module->m_scriptFunctions.PushLast(func);
|
||||
func->module = module;
|
||||
}
|
||||
if( addToEngine )
|
||||
|
@ -1513,7 +1607,7 @@ void asCReader::ReadTypeDeclaration(asCTypeInfo *type, int phase, bool *isExtern
|
|||
else if( phase == 2 )
|
||||
{
|
||||
// external shared types doesn't store this
|
||||
if ((type->flags & asOBJ_SHARED) && module->externalTypes.IndexOf(type) >= 0)
|
||||
if ((type->flags & asOBJ_SHARED) && module->m_externalTypes.IndexOf(type) >= 0)
|
||||
return;
|
||||
|
||||
if( type->flags & asOBJ_ENUM )
|
||||
|
@ -1668,8 +1762,6 @@ void asCReader::ReadTypeDeclaration(asCTypeInfo *type, int phase, bool *isExtern
|
|||
func->scriptData->byteCode.SetLength(0);
|
||||
func->ReleaseInternal();
|
||||
}
|
||||
module->scriptFunctions.PushLast(realFunc);
|
||||
realFunc->AddRefInternal();
|
||||
dontTranslate.Insert(realFunc, true);
|
||||
}
|
||||
}
|
||||
|
@ -1703,8 +1795,6 @@ void asCReader::ReadTypeDeclaration(asCTypeInfo *type, int phase, bool *isExtern
|
|||
if( savedFunctions[savedFunctions.GetLength()-1] == func )
|
||||
savedFunctions[savedFunctions.GetLength()-1] = realFunc;
|
||||
found = true;
|
||||
module->scriptFunctions.PushLast(realFunc);
|
||||
realFunc->AddRefInternal();
|
||||
dontTranslate.Insert(realFunc, true);
|
||||
break;
|
||||
}
|
||||
|
@ -1754,8 +1844,6 @@ void asCReader::ReadTypeDeclaration(asCTypeInfo *type, int phase, bool *isExtern
|
|||
if( savedFunctions[savedFunctions.GetLength()-1] == func )
|
||||
savedFunctions[savedFunctions.GetLength()-1] = realFunc;
|
||||
found = true;
|
||||
module->scriptFunctions.PushLast(realFunc);
|
||||
realFunc->AddRefInternal();
|
||||
dontTranslate.Insert(realFunc, true);
|
||||
break;
|
||||
}
|
||||
|
@ -1813,8 +1901,6 @@ void asCReader::ReadTypeDeclaration(asCTypeInfo *type, int phase, bool *isExtern
|
|||
if( savedFunctions[savedFunctions.GetLength()-1] == func )
|
||||
savedFunctions[savedFunctions.GetLength()-1] = realFunc;
|
||||
found = true;
|
||||
module->scriptFunctions.PushLast(realFunc);
|
||||
realFunc->AddRefInternal();
|
||||
dontTranslate.Insert(realFunc, true);
|
||||
break;
|
||||
}
|
||||
|
@ -1880,8 +1966,6 @@ void asCReader::ReadTypeDeclaration(asCTypeInfo *type, int phase, bool *isExtern
|
|||
if( savedFunctions[savedFunctions.GetLength()-1] == func )
|
||||
savedFunctions[savedFunctions.GetLength()-1] = realFunc;
|
||||
found = true;
|
||||
module->scriptFunctions.PushLast(realFunc);
|
||||
realFunc->AddRefInternal();
|
||||
dontTranslate.Insert(realFunc, true);
|
||||
break;
|
||||
}
|
||||
|
@ -1918,7 +2002,7 @@ void asCReader::ReadTypeDeclaration(asCTypeInfo *type, int phase, bool *isExtern
|
|||
else if( phase == 3 )
|
||||
{
|
||||
// external shared types doesn't store this
|
||||
if ((type->flags & asOBJ_SHARED) && module->externalTypes.IndexOf(type) >= 0)
|
||||
if ((type->flags & asOBJ_SHARED) && module->m_externalTypes.IndexOf(type) >= 0)
|
||||
return;
|
||||
|
||||
asCObjectType *ot = CastToObjectType(type);
|
||||
|
@ -2614,7 +2698,7 @@ void asCReader::ReadUsedGlobalProps()
|
|||
// Find the real property
|
||||
asCGlobalProperty *globProp = 0;
|
||||
if( moduleProp )
|
||||
globProp = module->scriptGlobals.GetFirst(nameSpace, name);
|
||||
globProp = module->m_scriptGlobals.GetFirst(nameSpace, name);
|
||||
else
|
||||
globProp = engine->registeredGlobalProps.GetFirst(nameSpace, name);
|
||||
|
||||
|
@ -2873,9 +2957,9 @@ void asCReader::TranslateFunction(asCScriptFunction *func)
|
|||
{
|
||||
// Translate the function id
|
||||
asUINT *fid = (asUINT*)&bc[n+1];
|
||||
if( *fid < module->bindInformations.GetLength() )
|
||||
if( *fid < module->m_bindInformations.GetLength() )
|
||||
{
|
||||
sBindInfo *bi = module->bindInformations[*fid];
|
||||
sBindInfo *bi = module->m_bindInformations[*fid];
|
||||
if( bi )
|
||||
*fid = bi->importedFunctionSignature->id;
|
||||
else
|
||||
|
@ -3819,12 +3903,12 @@ int asCWriter::Write()
|
|||
{
|
||||
TimeIt("store enums");
|
||||
|
||||
count = (asUINT)module->enumTypes.GetLength();
|
||||
count = (asUINT)module->m_enumTypes.GetLength();
|
||||
WriteEncodedInt64(count);
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
WriteTypeDeclaration(module->enumTypes[i], 1);
|
||||
WriteTypeDeclaration(module->enumTypes[i], 2);
|
||||
WriteTypeDeclaration(module->m_enumTypes[i], 1);
|
||||
WriteTypeDeclaration(module->m_enumTypes[i], 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3832,12 +3916,12 @@ int asCWriter::Write()
|
|||
{
|
||||
TimeIt("type declarations");
|
||||
|
||||
count = (asUINT)module->classTypes.GetLength();
|
||||
count = (asUINT)module->m_classTypes.GetLength();
|
||||
WriteEncodedInt64(count);
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
// Store only the name of the class/interface types
|
||||
WriteTypeDeclaration(module->classTypes[i], 1);
|
||||
WriteTypeDeclaration(module->m_classTypes[i], 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3845,21 +3929,21 @@ int asCWriter::Write()
|
|||
{
|
||||
TimeIt("func defs");
|
||||
|
||||
count = (asUINT)module->funcDefs.GetLength();
|
||||
count = (asUINT)module->m_funcDefs.GetLength();
|
||||
WriteEncodedInt64(count);
|
||||
for( i = 0; i < count; i++ )
|
||||
WriteFunction(module->funcDefs[i]->funcdef);
|
||||
WriteFunction(module->m_funcDefs[i]->funcdef);
|
||||
}
|
||||
|
||||
// Now store all interface methods
|
||||
{
|
||||
TimeIt("interface methods");
|
||||
|
||||
count = (asUINT)module->classTypes.GetLength();
|
||||
count = (asUINT)module->m_classTypes.GetLength();
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
if( module->classTypes[i]->IsInterface() )
|
||||
WriteTypeDeclaration(module->classTypes[i], 2);
|
||||
if( module->m_classTypes[i]->IsInterface() )
|
||||
WriteTypeDeclaration(module->m_classTypes[i], 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3869,8 +3953,8 @@ int asCWriter::Write()
|
|||
|
||||
for( i = 0; i < count; ++i )
|
||||
{
|
||||
if( !module->classTypes[i]->IsInterface() )
|
||||
WriteTypeDeclaration(module->classTypes[i], 2);
|
||||
if( !module->m_classTypes[i]->IsInterface() )
|
||||
WriteTypeDeclaration(module->m_classTypes[i], 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3880,8 +3964,8 @@ int asCWriter::Write()
|
|||
|
||||
for( i = 0; i < count; ++i )
|
||||
{
|
||||
if( !module->classTypes[i]->IsInterface() )
|
||||
WriteTypeDeclaration(module->classTypes[i], 3);
|
||||
if( !module->m_classTypes[i]->IsInterface() )
|
||||
WriteTypeDeclaration(module->m_classTypes[i], 3);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3889,12 +3973,12 @@ int asCWriter::Write()
|
|||
{
|
||||
TimeIt("type defs");
|
||||
|
||||
count = (asUINT)module->typeDefs.GetLength();
|
||||
count = (asUINT)module->m_typeDefs.GetLength();
|
||||
WriteEncodedInt64(count);
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
WriteTypeDeclaration(module->typeDefs[i], 1);
|
||||
WriteTypeDeclaration(module->typeDefs[i], 2);
|
||||
WriteTypeDeclaration(module->m_typeDefs[i], 1);
|
||||
WriteTypeDeclaration(module->m_typeDefs[i], 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3902,9 +3986,9 @@ int asCWriter::Write()
|
|||
{
|
||||
TimeIt("script globals");
|
||||
|
||||
count = (asUINT)module->scriptGlobals.GetSize();
|
||||
count = (asUINT)module->m_scriptGlobals.GetSize();
|
||||
WriteEncodedInt64(count);
|
||||
asCSymbolTable<asCGlobalProperty>::iterator it = module->scriptGlobals.List();
|
||||
asCSymbolTable<asCGlobalProperty>::iterator it = module->m_scriptGlobals.List();
|
||||
for( ; it; it++ )
|
||||
WriteGlobalProperty(*it);
|
||||
}
|
||||
|
@ -3914,21 +3998,21 @@ int asCWriter::Write()
|
|||
TimeIt("scriptFunctions");
|
||||
|
||||
count = 0;
|
||||
for( i = 0; i < module->scriptFunctions.GetLength(); i++ )
|
||||
if( module->scriptFunctions[i]->objectType == 0 )
|
||||
for( i = 0; i < module->m_scriptFunctions.GetLength(); i++ )
|
||||
if( module->m_scriptFunctions[i]->objectType == 0 )
|
||||
count++;
|
||||
WriteEncodedInt64(count);
|
||||
for( i = 0; i < module->scriptFunctions.GetLength(); ++i )
|
||||
if( module->scriptFunctions[i]->objectType == 0 )
|
||||
WriteFunction(module->scriptFunctions[i]);
|
||||
for( i = 0; i < module->m_scriptFunctions.GetLength(); ++i )
|
||||
if( module->m_scriptFunctions[i]->objectType == 0 )
|
||||
WriteFunction(module->m_scriptFunctions[i]);
|
||||
}
|
||||
|
||||
// globalFunctions[]
|
||||
{
|
||||
TimeIt("globalFunctions");
|
||||
|
||||
count = (int)module->globalFunctions.GetSize();
|
||||
asCSymbolTable<asCScriptFunction>::iterator funcIt = module->globalFunctions.List();
|
||||
count = (int)module->m_globalFunctions.GetSize();
|
||||
asCSymbolTable<asCScriptFunction>::iterator funcIt = module->m_globalFunctions.List();
|
||||
WriteEncodedInt64(count);
|
||||
while( funcIt )
|
||||
{
|
||||
|
@ -3941,12 +4025,12 @@ int asCWriter::Write()
|
|||
{
|
||||
TimeIt("bindInformations");
|
||||
|
||||
count = (asUINT)module->bindInformations.GetLength();
|
||||
count = (asUINT)module->m_bindInformations.GetLength();
|
||||
WriteEncodedInt64(count);
|
||||
for( i = 0; i < count; ++i )
|
||||
{
|
||||
WriteFunction(module->bindInformations[i]->importedFunctionSignature);
|
||||
WriteString(&module->bindInformations[i]->importFromModule);
|
||||
WriteFunction(module->m_bindInformations[i]->importedFunctionSignature);
|
||||
WriteString(&module->m_bindInformations[i]->importFromModule);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4026,9 +4110,9 @@ void asCWriter::WriteUsedFunctions()
|
|||
// Is the function from the module or the application?
|
||||
c = func->module ? 'm' : 'a';
|
||||
|
||||
// Functions and methods that are shared and not owned by the module can be
|
||||
// stored as 's' to tell the reader that these are received from other modules.
|
||||
if (c == 'm' && func->IsShared() && module->scriptFunctions.IndexOf(func) < 0 )
|
||||
// Functions and methods that are shared should be stored as 's' as the bytecode
|
||||
// may be imported from other modules (even if the current module have received ownership)
|
||||
if (c == 'm' && func->IsShared() )
|
||||
c = 's';
|
||||
|
||||
WriteData(&c, 1);
|
||||
|
@ -4164,13 +4248,13 @@ void asCWriter::WriteFunction(asCScriptFunction* func)
|
|||
if( func->funcType == asFUNC_SCRIPT )
|
||||
{
|
||||
// Skip this for external shared entities
|
||||
if (module->externalTypes.IndexOf(func->objectType) >= 0)
|
||||
if (module->m_externalTypes.IndexOf(func->objectType) >= 0)
|
||||
return;
|
||||
|
||||
char bits = 0;
|
||||
bits += func->IsShared() ? 1 : 0;
|
||||
bits += func->dontCleanUpOnException ? 2 : 0;
|
||||
if (module->externalFunctions.IndexOf(func) >= 0)
|
||||
if (module->m_externalFunctions.IndexOf(func) >= 0)
|
||||
bits += 4;
|
||||
if (func->scriptData->objVariablePos.GetLength() || func->scriptData->objVariableInfo.GetLength())
|
||||
bits += 8;
|
||||
|
@ -4305,7 +4389,7 @@ void asCWriter::WriteFunction(asCScriptFunction* func)
|
|||
{
|
||||
char bits = 0;
|
||||
bits += func->IsShared() ? 1 : 0;
|
||||
if (module->externalTypes.IndexOf(func->funcdefType) >= 0)
|
||||
if (module->m_externalTypes.IndexOf(func->funcdefType) >= 0)
|
||||
bits += 2;
|
||||
WriteData(&bits,1);
|
||||
}
|
||||
|
@ -4343,7 +4427,7 @@ void asCWriter::WriteTypeDeclaration(asCTypeInfo *type, int phase)
|
|||
if ((type->flags & asOBJ_SHARED))
|
||||
{
|
||||
char c = ' ';
|
||||
if (module->externalTypes.IndexOf(type) >= 0)
|
||||
if (module->m_externalTypes.IndexOf(type) >= 0)
|
||||
c = 'e';
|
||||
WriteData(&c, 1);
|
||||
}
|
||||
|
@ -4351,7 +4435,7 @@ void asCWriter::WriteTypeDeclaration(asCTypeInfo *type, int phase)
|
|||
else if( phase == 2 )
|
||||
{
|
||||
// external shared types doesn't need to save this
|
||||
if ((type->flags & asOBJ_SHARED) && module->externalTypes.IndexOf(type) >= 0)
|
||||
if ((type->flags & asOBJ_SHARED) && module->m_externalTypes.IndexOf(type) >= 0)
|
||||
return;
|
||||
|
||||
if(type->flags & asOBJ_ENUM )
|
||||
|
@ -4429,7 +4513,7 @@ void asCWriter::WriteTypeDeclaration(asCTypeInfo *type, int phase)
|
|||
else if( phase == 3 )
|
||||
{
|
||||
// external shared types doesn't need to save this
|
||||
if ((type->flags & asOBJ_SHARED) && module->externalTypes.IndexOf(type) >= 0)
|
||||
if ((type->flags & asOBJ_SHARED) && module->m_externalTypes.IndexOf(type) >= 0)
|
||||
return;
|
||||
|
||||
// properties[]
|
||||
|
@ -5046,8 +5130,8 @@ void asCWriter::WriteByteCode(asCScriptFunction *func)
|
|||
{
|
||||
// Translate the function id
|
||||
int funcId = tmpBC[1];
|
||||
for( asUINT n = 0; n < module->bindInformations.GetLength(); n++ )
|
||||
if( module->bindInformations[n]->importedFunctionSignature->id == funcId )
|
||||
for( asUINT n = 0; n < module->m_bindInformations.GetLength(); n++ )
|
||||
if( module->m_bindInformations[n]->importedFunctionSignature->id == funcId )
|
||||
{
|
||||
funcId = n;
|
||||
break;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2019 Andreas Jonsson
|
||||
Copyright (c) 2003-2020 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
|
@ -218,6 +218,9 @@ AS_API const char * asGetLibraryOptions()
|
|||
#endif
|
||||
#ifdef AS_SPARC
|
||||
"AS_SPARC "
|
||||
#endif
|
||||
#ifdef AS_ARM64
|
||||
"AS_ARM64 "
|
||||
#endif
|
||||
;
|
||||
|
||||
|
@ -919,15 +922,15 @@ asCModule *asCScriptEngine::FindNewOwnerForSharedType(asCTypeInfo *in_type, asCM
|
|||
asCModule *mod = scriptModules[n];
|
||||
if( mod == in_type->module ) continue;
|
||||
if( in_type->flags & asOBJ_ENUM )
|
||||
foundIdx = mod->enumTypes.IndexOf(CastToEnumType(in_type));
|
||||
foundIdx = mod->m_enumTypes.IndexOf(CastToEnumType(in_type));
|
||||
else if (in_type->flags & asOBJ_TYPEDEF)
|
||||
foundIdx = mod->typeDefs.IndexOf(CastToTypedefType(in_type));
|
||||
foundIdx = mod->m_typeDefs.IndexOf(CastToTypedefType(in_type));
|
||||
else if (in_type->flags & asOBJ_FUNCDEF)
|
||||
foundIdx = mod->funcDefs.IndexOf(CastToFuncdefType(in_type));
|
||||
foundIdx = mod->m_funcDefs.IndexOf(CastToFuncdefType(in_type));
|
||||
else if (in_type->flags & asOBJ_TEMPLATE)
|
||||
foundIdx = mod->templateInstances.IndexOf(CastToObjectType(in_type));
|
||||
foundIdx = mod->m_templateInstances.IndexOf(CastToObjectType(in_type));
|
||||
else
|
||||
foundIdx = mod->classTypes.IndexOf(CastToObjectType(in_type));
|
||||
foundIdx = mod->m_classTypes.IndexOf(CastToObjectType(in_type));
|
||||
|
||||
if( foundIdx >= 0 )
|
||||
{
|
||||
|
@ -948,13 +951,30 @@ asCModule *asCScriptEngine::FindNewOwnerForSharedFunc(asCScriptFunction *in_func
|
|||
if( in_func->module != in_mod)
|
||||
return in_func->module;
|
||||
|
||||
if (in_func->objectType && in_func->objectType->module &&
|
||||
in_func->objectType->module != in_func->module)
|
||||
{
|
||||
// The object type for the method has already been transferred to
|
||||
// another module, so transfer the method to the same module
|
||||
in_func->module = in_func->objectType->module;
|
||||
|
||||
// Make sure the function is listed in the module
|
||||
// The compiler may not have done this earlier, since the object
|
||||
// type is shared and originally compiled from another module
|
||||
if (in_func->module->m_scriptFunctions.IndexOf(in_func) < 0)
|
||||
{
|
||||
in_func->module->m_scriptFunctions.PushLast(in_func);
|
||||
in_func->AddRefInternal();
|
||||
}
|
||||
}
|
||||
|
||||
for( asUINT n = 0; n < scriptModules.GetLength(); n++ )
|
||||
{
|
||||
// TODO: optimize: If the modules already stored the shared types separately, this would be quicker
|
||||
int foundIdx = -1;
|
||||
asCModule *mod = scriptModules[n];
|
||||
if( mod == in_func->module ) continue;
|
||||
foundIdx = mod->scriptFunctions.IndexOf(in_func);
|
||||
foundIdx = mod->m_scriptFunctions.IndexOf(in_func);
|
||||
|
||||
if( foundIdx >= 0 )
|
||||
{
|
||||
|
@ -1495,7 +1515,9 @@ int asCScriptEngine::RegisterObjectProperty(const char *obj, const char *declara
|
|||
prop->isCompositeIndirect = isCompositeIndirect;
|
||||
prop->accessMask = defaultAccessMask;
|
||||
|
||||
CastToObjectType(dt.GetTypeInfo())->properties.PushLast(prop);
|
||||
asCObjectType *ot = CastToObjectType(dt.GetTypeInfo());
|
||||
asUINT idx = ot->properties.GetLength();
|
||||
ot->properties.PushLast(prop);
|
||||
|
||||
// Add references to types so they are not released too early
|
||||
if( type.GetTypeInfo() )
|
||||
|
@ -1509,7 +1531,8 @@ int asCScriptEngine::RegisterObjectProperty(const char *obj, const char *declara
|
|||
|
||||
currentGroup->AddReferencesForType(this, type.GetTypeInfo());
|
||||
|
||||
return asSUCCESS;
|
||||
// Return the index of the property to signal success
|
||||
return idx;
|
||||
}
|
||||
|
||||
// interface
|
||||
|
@ -2111,6 +2134,8 @@ int asCScriptEngine::RegisterBehaviourToObjectType(asCObjectType *objectType, as
|
|||
}
|
||||
else if( behaviour == asBEHAVE_LIST_CONSTRUCT )
|
||||
{
|
||||
func.name = "$list";
|
||||
|
||||
// Verify that the return type is void
|
||||
if( func.returnType != asCDataType::CreatePrimitive(ttVoid, false) )
|
||||
{
|
||||
|
@ -2166,6 +2191,9 @@ int asCScriptEngine::RegisterBehaviourToObjectType(asCObjectType *objectType, as
|
|||
}
|
||||
else if( behaviour == asBEHAVE_FACTORY || behaviour == asBEHAVE_LIST_FACTORY )
|
||||
{
|
||||
if( behaviour == asBEHAVE_LIST_FACTORY )
|
||||
func.name = "$list";
|
||||
|
||||
// Must be a ref type and must not have asOBJ_NOHANDLE
|
||||
if( !(objectType->flags & asOBJ_REF) || (objectType->flags & asOBJ_NOHANDLE) )
|
||||
{
|
||||
|
@ -2565,13 +2593,14 @@ int asCScriptEngine::RegisterGlobalProperty(const char *declaration, void *point
|
|||
prop->SetRegisteredAddress(pointer);
|
||||
varAddressMap.Insert(prop->GetAddressOfValue(), prop);
|
||||
|
||||
registeredGlobalProps.Put(prop);
|
||||
asUINT idx = registeredGlobalProps.Put(prop);
|
||||
prop->AddRef();
|
||||
currentGroup->globalProps.PushLast(prop);
|
||||
|
||||
currentGroup->AddReferencesForType(this, type.GetTypeInfo());
|
||||
|
||||
return asSUCCESS;
|
||||
// Return the index of the property to signal success
|
||||
return int(idx);
|
||||
}
|
||||
|
||||
// internal
|
||||
|
@ -2650,10 +2679,13 @@ int asCScriptEngine::GetGlobalPropertyByIndex(asUINT index, const char **name, c
|
|||
}
|
||||
|
||||
// interface
|
||||
int asCScriptEngine::GetGlobalPropertyIndexByName(const char *name) const
|
||||
int asCScriptEngine::GetGlobalPropertyIndexByName(const char *in_name) const
|
||||
{
|
||||
asSNameSpace *ns = defaultNamespace;
|
||||
|
||||
asCString name;
|
||||
asSNameSpace *ns = 0;
|
||||
if( DetermineNameAndNamespace(in_name, defaultNamespace, name, ns) < 0 )
|
||||
return asINVALID_ARG;
|
||||
|
||||
// Find the global var id
|
||||
while( ns )
|
||||
{
|
||||
|
@ -3254,13 +3286,13 @@ asCModule *asCScriptEngine::GetModule(const char *name, bool create)
|
|||
asCModule *retModule = 0;
|
||||
|
||||
ACQUIRESHARED(engineRWLock);
|
||||
if( lastModule && lastModule->name == name )
|
||||
if( lastModule && lastModule->m_name == name )
|
||||
retModule = lastModule;
|
||||
else
|
||||
{
|
||||
// TODO: optimize: Improve linear search
|
||||
for( asUINT n = 0; n < scriptModules.GetLength(); ++n )
|
||||
if( scriptModules[n] && scriptModules[n]->name == name )
|
||||
if( scriptModules[n] && scriptModules[n]->m_name == name )
|
||||
{
|
||||
retModule = scriptModules[n];
|
||||
break;
|
||||
|
@ -3376,9 +3408,9 @@ asCObjectType *asCScriptEngine::GetTemplateInstanceType(asCObjectType *templateT
|
|||
// It may be without ownership if it was previously created from application with for example GetTypeInfoByDecl
|
||||
type->module = requestingModule;
|
||||
}
|
||||
if( !requestingModule->templateInstances.Exists(type) )
|
||||
if( !requestingModule->m_templateInstances.Exists(type) )
|
||||
{
|
||||
requestingModule->templateInstances.PushLast(type);
|
||||
requestingModule->m_templateInstances.PushLast(type);
|
||||
type->AddRefInternal();
|
||||
}
|
||||
}
|
||||
|
@ -3418,7 +3450,7 @@ asCObjectType *asCScriptEngine::GetTemplateInstanceType(asCObjectType *templateT
|
|||
{
|
||||
// Set the ownership of this template type
|
||||
ot->module = requestingModule;
|
||||
requestingModule->templateInstances.PushLast(ot);
|
||||
requestingModule->m_templateInstances.PushLast(ot);
|
||||
ot->AddRefInternal();
|
||||
}
|
||||
else
|
||||
|
@ -3434,7 +3466,7 @@ asCObjectType *asCScriptEngine::GetTemplateInstanceType(asCObjectType *templateT
|
|||
ot->module = subTypes[n].GetTypeInfo()->module;
|
||||
if( ot->module )
|
||||
{
|
||||
ot->module->templateInstances.PushLast(ot);
|
||||
ot->module->m_templateInstances.PushLast(ot);
|
||||
ot->AddRefInternal();
|
||||
break;
|
||||
}
|
||||
|
@ -3458,7 +3490,7 @@ asCObjectType *asCScriptEngine::GetTemplateInstanceType(asCObjectType *templateT
|
|||
ot->templateSubTypes.SetLength(0);
|
||||
if( ot->module )
|
||||
{
|
||||
ot->module->templateInstances.RemoveValue(ot);
|
||||
ot->module->m_templateInstances.RemoveValue(ot);
|
||||
ot->ReleaseInternal();
|
||||
}
|
||||
ot->ReleaseInternal();
|
||||
|
@ -5778,7 +5810,7 @@ asCFuncdefType *asCScriptEngine::FindMatchingFuncdef(asCScriptFunction *func, as
|
|||
// Add the new funcdef to the module so it will
|
||||
// be available when saving the bytecode
|
||||
funcDef->module = module;
|
||||
module->funcDefs.PushLast(funcDef); // the refCount was already accounted for in the constructor
|
||||
module->AddFuncDef(funcDef); // the refCount was already accounted for in the constructor
|
||||
}
|
||||
|
||||
// Observe, if the funcdef is created without informing a module a reference will be stored in the
|
||||
|
@ -5790,9 +5822,9 @@ asCFuncdefType *asCScriptEngine::FindMatchingFuncdef(asCScriptFunction *func, as
|
|||
{
|
||||
// Unless this is a registered funcDef the returned funcDef must
|
||||
// be stored as part of the module for saving/loading bytecode
|
||||
if (!module->funcDefs.Exists(funcDef))
|
||||
if (!module->m_funcDefs.Exists(funcDef))
|
||||
{
|
||||
module->funcDefs.PushLast(funcDef);
|
||||
module->AddFuncDef(funcDef);
|
||||
funcDef->AddRefInternal();
|
||||
}
|
||||
else
|
||||
|
@ -6026,9 +6058,13 @@ asITypeInfo *asCScriptEngine::GetObjectTypeByIndex(asUINT index) const
|
|||
}
|
||||
|
||||
// interface
|
||||
asITypeInfo *asCScriptEngine::GetTypeInfoByName(const char *name) const
|
||||
asITypeInfo *asCScriptEngine::GetTypeInfoByName(const char *in_name) const
|
||||
{
|
||||
asSNameSpace *ns = defaultNamespace;
|
||||
asCString name;
|
||||
asSNameSpace *ns = 0;
|
||||
if( DetermineNameAndNamespace(in_name, defaultNamespace, name, ns) < 0 )
|
||||
return 0;
|
||||
|
||||
while (ns)
|
||||
{
|
||||
// Check the object types
|
||||
|
@ -6071,6 +6107,49 @@ asITypeInfo *asCScriptEngine::GetTypeInfoByName(const char *name) const
|
|||
return 0;
|
||||
}
|
||||
|
||||
// internal
|
||||
int asCScriptEngine::DetermineNameAndNamespace(const char *in_name, asSNameSpace *implicitNs, asCString &out_name, asSNameSpace *&out_ns) const
|
||||
{
|
||||
if( in_name == 0 )
|
||||
return asINVALID_ARG;
|
||||
|
||||
asCString name = in_name;
|
||||
asCString scope;
|
||||
asSNameSpace *ns = implicitNs;
|
||||
|
||||
// Check if the given name contains a scope
|
||||
int pos = name.FindLast("::");
|
||||
if( pos >= 0 )
|
||||
{
|
||||
scope = name.SubString(0, pos);
|
||||
name = name.SubString(pos+2);
|
||||
if( pos == 0 )
|
||||
{
|
||||
// The scope is '::' so the search must start in the global namespace
|
||||
ns = nameSpaces[0];
|
||||
}
|
||||
else if( scope.SubString(0, 2) == "::" )
|
||||
{
|
||||
// The scope starts with '::' so the given scope is fully qualified
|
||||
ns = FindNameSpace(scope.SubString(2).AddressOf());
|
||||
}
|
||||
else
|
||||
{
|
||||
// The scope doesn't start with '::' so it is relative to the current namespace
|
||||
if( implicitNs->name == "" )
|
||||
ns = FindNameSpace(scope.AddressOf());
|
||||
else
|
||||
ns = FindNameSpace((implicitNs->name + "::" + scope).AddressOf());
|
||||
}
|
||||
}
|
||||
|
||||
out_name = name;
|
||||
out_ns = ns;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// interface
|
||||
asITypeInfo *asCScriptEngine::GetTypeInfoById(int typeId) const
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2018 Andreas Jonsson
|
||||
Copyright (c) 2003-2019 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
|
@ -305,6 +305,8 @@ public:
|
|||
|
||||
asCFuncdefType *FindMatchingFuncdef(asCScriptFunction *func, asCModule *mod);
|
||||
|
||||
int DetermineNameAndNamespace(const char *in_name, asSNameSpace *implicitNs, asCString &out_name, asSNameSpace *&out_ns) const;
|
||||
|
||||
// Global property management
|
||||
asCGlobalProperty *AllocateGlobalProperty();
|
||||
void RemoveGlobalProperty(asCGlobalProperty *prop);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2019 Andreas Jonsson
|
||||
Copyright (c) 2003-2020 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
|
@ -584,9 +584,7 @@ bool asCScriptFunction::IsCompatibleWithTypeId(int typeId) const
|
|||
const char *asCScriptFunction::GetModuleName() const
|
||||
{
|
||||
if( module )
|
||||
{
|
||||
return module->name.AddressOf();
|
||||
}
|
||||
return module->GetName();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2018 Andreas Jonsson
|
||||
Copyright (c) 2003-2019 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
|
@ -888,30 +888,43 @@ asCScriptObject &ScriptObject_Assignment(asCScriptObject *other, asCScriptObject
|
|||
|
||||
asCScriptObject &asCScriptObject::operator=(const asCScriptObject &other)
|
||||
{
|
||||
if( &other != this )
|
||||
CopyFromAs(&other, objType);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// internal
|
||||
int asCScriptObject::CopyFromAs(const asCScriptObject *other, asCObjectType *in_objType)
|
||||
{
|
||||
if( other != this )
|
||||
{
|
||||
if( !other.objType->DerivesFrom(objType) )
|
||||
if( !other->objType->DerivesFrom(in_objType) )
|
||||
{
|
||||
// We cannot allow a value assignment from a type that isn't the same or
|
||||
// derives from this type as the member properties may not have the same layout
|
||||
asIScriptContext *ctx = asGetActiveContext();
|
||||
ctx->SetException(TXT_MISMATCH_IN_VALUE_ASSIGN);
|
||||
return *this;
|
||||
return asERROR;
|
||||
}
|
||||
|
||||
// If the script class implements the opAssign method, it should be called
|
||||
asCScriptEngine *engine = objType->engine;
|
||||
asCScriptFunction *func = engine->scriptFunctions[objType->beh.copy];
|
||||
asCScriptEngine *engine = in_objType->engine;
|
||||
asCScriptFunction *func = engine->scriptFunctions[in_objType->beh.copy];
|
||||
if( func->funcType == asFUNC_SYSTEM )
|
||||
{
|
||||
// Copy all properties
|
||||
for( asUINT n = 0; n < objType->properties.GetLength(); n++ )
|
||||
// If derived, use the base class' assignment operator to copy the inherited
|
||||
// properties. Then only copy new properties for the derived class
|
||||
if( in_objType->derivedFrom )
|
||||
CopyFromAs(other, in_objType->derivedFrom);
|
||||
|
||||
for( asUINT n = in_objType->derivedFrom ? in_objType->derivedFrom->properties.GetLength() : 0;
|
||||
n < in_objType->properties.GetLength();
|
||||
n++ )
|
||||
{
|
||||
asCObjectProperty *prop = objType->properties[n];
|
||||
asCObjectProperty *prop = in_objType->properties[n];
|
||||
if( prop->type.IsObject() )
|
||||
{
|
||||
void **dst = (void**)(((char*)this) + prop->byteOffset);
|
||||
void **src = (void**)(((char*)&other) + prop->byteOffset);
|
||||
void **src = (void**)(((char*)other) + prop->byteOffset);
|
||||
if( !prop->type.IsObjectHandle() )
|
||||
{
|
||||
if( prop->type.IsReference() || (prop->type.GetTypeInfo()->flags & asOBJ_REF) )
|
||||
|
@ -925,7 +938,7 @@ asCScriptObject &asCScriptObject::operator=(const asCScriptObject &other)
|
|||
else if (prop->type.IsFuncdef())
|
||||
{
|
||||
asCScriptFunction **dst = (asCScriptFunction**)(((char*)this) + prop->byteOffset);
|
||||
asCScriptFunction **src = (asCScriptFunction**)(((char*)&other) + prop->byteOffset);
|
||||
asCScriptFunction **src = (asCScriptFunction**)(((char*)other) + prop->byteOffset);
|
||||
if (*dst)
|
||||
(*dst)->Release();
|
||||
*dst = *src;
|
||||
|
@ -935,7 +948,7 @@ asCScriptObject &asCScriptObject::operator=(const asCScriptObject &other)
|
|||
else
|
||||
{
|
||||
void *dst = ((char*)this) + prop->byteOffset;
|
||||
void *src = ((char*)&other) + prop->byteOffset;
|
||||
void *src = ((char*)other) + prop->byteOffset;
|
||||
memcpy(dst, src, prop->type.GetSizeInMemoryBytes());
|
||||
}
|
||||
}
|
||||
|
@ -961,24 +974,20 @@ asCScriptObject &asCScriptObject::operator=(const asCScriptObject &other)
|
|||
// Request a context from the engine
|
||||
ctx = engine->RequestContext();
|
||||
if( ctx == 0 )
|
||||
{
|
||||
// TODO: How to best report this failure?
|
||||
return *this;
|
||||
}
|
||||
return asERROR;
|
||||
}
|
||||
|
||||
r = ctx->Prepare(engine->scriptFunctions[objType->beh.copy]);
|
||||
r = ctx->Prepare(engine->scriptFunctions[in_objType->beh.copy]);
|
||||
if( r < 0 )
|
||||
{
|
||||
if( isNested )
|
||||
ctx->PopState();
|
||||
else
|
||||
engine->ReturnContext(ctx);
|
||||
// TODO: How to best report this failure?
|
||||
return *this;
|
||||
return r;
|
||||
}
|
||||
|
||||
r = ctx->SetArgAddress(0, const_cast<asCScriptObject*>(&other));
|
||||
r = ctx->SetArgAddress(0, const_cast<asCScriptObject*>(other));
|
||||
asASSERT( r >= 0 );
|
||||
r = ctx->SetObject(this);
|
||||
asASSERT( r >= 0 );
|
||||
|
@ -1014,7 +1023,7 @@ asCScriptObject &asCScriptObject::operator=(const asCScriptObject &other)
|
|||
// Return the context to the engine
|
||||
engine->ReturnContext(ctx);
|
||||
}
|
||||
return *this;
|
||||
return asERROR;
|
||||
}
|
||||
|
||||
if( isNested )
|
||||
|
@ -1027,10 +1036,10 @@ asCScriptObject &asCScriptObject::operator=(const asCScriptObject &other)
|
|||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
return asSUCCESS;
|
||||
}
|
||||
|
||||
int asCScriptObject::CopyFrom(asIScriptObject *other)
|
||||
int asCScriptObject::CopyFrom(const asIScriptObject *other)
|
||||
{
|
||||
if( other == 0 ) return asINVALID_ARG;
|
||||
|
||||
|
@ -1039,7 +1048,7 @@ int asCScriptObject::CopyFrom(asIScriptObject *other)
|
|||
|
||||
*this = *(asCScriptObject*)other;
|
||||
|
||||
return 0;
|
||||
return asSUCCESS;
|
||||
}
|
||||
|
||||
void *asCScriptObject::AllocateUninitializedObject(asCObjectType *in_objType, asCScriptEngine *engine)
|
||||
|
@ -1089,19 +1098,19 @@ void asCScriptObject::FreeObject(void *ptr, asCObjectType *in_objType, asCScript
|
|||
}
|
||||
}
|
||||
|
||||
void asCScriptObject::CopyObject(void *src, void *dst, asCObjectType *in_objType, asCScriptEngine *engine)
|
||||
void asCScriptObject::CopyObject(const void *src, void *dst, asCObjectType *in_objType, asCScriptEngine *engine)
|
||||
{
|
||||
int funcIndex = in_objType->beh.copy;
|
||||
if( funcIndex )
|
||||
{
|
||||
asCScriptFunction *func = engine->scriptFunctions[in_objType->beh.copy];
|
||||
if( func->funcType == asFUNC_SYSTEM )
|
||||
engine->CallObjectMethod(dst, src, funcIndex);
|
||||
engine->CallObjectMethod(dst, const_cast<void*>(src), funcIndex);
|
||||
else
|
||||
{
|
||||
// Call the script class' opAssign method
|
||||
asASSERT(in_objType->flags & asOBJ_SCRIPT_OBJECT );
|
||||
reinterpret_cast<asCScriptObject*>(dst)->CopyFrom(reinterpret_cast<asCScriptObject*>(src));
|
||||
reinterpret_cast<asCScriptObject*>(dst)->CopyFrom(reinterpret_cast<const asCScriptObject*>(src));
|
||||
}
|
||||
}
|
||||
else if( in_objType->size && (in_objType->flags & asOBJ_POD) )
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2018 Andreas Jonsson
|
||||
Copyright (c) 2003-2019 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
|
@ -94,7 +94,7 @@ public:
|
|||
|
||||
// Miscellaneous
|
||||
asIScriptEngine *GetEngine() const;
|
||||
int CopyFrom(asIScriptObject *other);
|
||||
int CopyFrom(const asIScriptObject *other);
|
||||
|
||||
// User data
|
||||
void *SetUserData(void *data, asPWORD type = 0);
|
||||
|
@ -119,8 +119,9 @@ public:
|
|||
// Used for properties
|
||||
void *AllocateUninitializedObject(asCObjectType *objType, asCScriptEngine *engine);
|
||||
void FreeObject(void *ptr, asCObjectType *objType, asCScriptEngine *engine);
|
||||
void CopyObject(void *src, void *dst, asCObjectType *objType, asCScriptEngine *engine);
|
||||
void CopyObject(const void *src, void *dst, asCObjectType *objType, asCScriptEngine *engine);
|
||||
void CopyHandle(asPWORD *src, asPWORD *dst, asCObjectType *objType, asCScriptEngine *engine);
|
||||
int CopyFromAs(const asCScriptObject *other, asCObjectType *objType);
|
||||
|
||||
void CallDestructor();
|
||||
|
||||
|
|
|
@ -141,7 +141,7 @@ public:
|
|||
|
||||
private:
|
||||
// Don't allow assignment
|
||||
asCSymbolTable<T>& operator=(const asCSymbolTable<T> &) { return *this; }
|
||||
asCSymbolTable<T>& operator=(const asCSymbolTable<T> &other) { return *this; }
|
||||
|
||||
friend class asCSymbolTableIterator<T, T>;
|
||||
friend class asCSymbolTableIterator<T, const T>;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2017 Andreas Jonsson
|
||||
Copyright (c) 2003-2020 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
|
@ -416,7 +416,8 @@ asCFuncdefType::asCFuncdefType(asCScriptEngine *en, asCScriptFunction *func) : a
|
|||
asASSERT(func->funcdefType == 0);
|
||||
|
||||
// A function pointer is special kind of reference type
|
||||
flags = asOBJ_REF | asOBJ_FUNCDEF | (func->IsShared() ? asOBJ_SHARED : 0);
|
||||
// It must be possible to garbage collect, as funcdefs can form circular references if used as delegates
|
||||
flags = asOBJ_REF | asOBJ_GC | asOBJ_FUNCDEF | (func->IsShared() ? asOBJ_SHARED : 0);
|
||||
name = func->name;
|
||||
nameSpace = func->nameSpace;
|
||||
module = func->module;
|
||||
|
|
|
@ -57,7 +57,6 @@ function registerFiles(directoryName: string) {
|
|||
const filepath = directoryName + path.sep + file;
|
||||
var uri = "file://" + filepath;
|
||||
if (!allFiles.get(uri)) {
|
||||
connection.console.log("Loaded new file at uri " + uri);
|
||||
let td = TextDocument.create(uri, "Angelscript", 0, fs.readFileSync(filepath, 'utf8'));
|
||||
allFiles.set(uri, td);
|
||||
}
|
||||
|
@ -168,9 +167,9 @@ function loadScript(textDocument: TextDocument): void {
|
|||
async function validateBuild(): Promise<void> {
|
||||
var r = database.build();
|
||||
if (r < -1) {
|
||||
connection.console.log(r.toString());
|
||||
console.log(r.toString());
|
||||
}
|
||||
connection.console.log("Building");
|
||||
console.log("Building");
|
||||
|
||||
var messages = database.messages();
|
||||
let diagnostics: Map<string, Diagnostic[]> = new Map<string, Diagnostic[]>();
|
||||
|
|
Loading…
Reference in New Issue