Update to angelscript 2.35

This commit is contained in:
Deukhoofd 2021-08-30 10:50:47 +02:00
parent 18e71dfe13
commit fac54acbc9
Signed by: Deukhoofd
GPG Key ID: F63E044490819F6F
34 changed files with 2187 additions and 1072 deletions

View File

@ -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"
}
}

View File

@ -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})

View File

@ -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));
// TODO: Use std::sort for primitive types too
int j = i - 1;
while( j >= start && Less(GetDataPointer(tmp), At(j), asc, cmpContext, cache) )
// 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));

View File

@ -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);

View File

@ -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;

View File

@ -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
// 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();
}
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

View File

@ -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"));

View File

@ -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)

View File

@ -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") )
{

View File

@ -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.

View File

@ -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) )

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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> &parameter
// 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);
}

View File

@ -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;

View File

@ -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

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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
@ -242,6 +242,11 @@ void asCMemoryMgr::FreeScriptNode(void *ptr)
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

View File

@ -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);
asCString name;
// 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);
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

View File

@ -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;

View File

@ -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,9 +2679,12 @@ 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
{

View File

@ -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);

View File

@ -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;
}

View File

@ -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) )

View File

@ -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();

View File

@ -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>;

View File

@ -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;

View File

@ -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[]>();