Update to Angelscript 2.35.1

This commit is contained in:
2022-04-02 15:12:50 +02:00
parent badd37a7d3
commit 6734aa44ec
33 changed files with 650 additions and 316 deletions

View File

@@ -37,7 +37,6 @@
#include "as_atomic.h"
BEGIN_AS_NAMESPACE
const asUINT MAX_VALUE = 100000000;
asCAtomic::asCAtomic()
{
@@ -48,7 +47,7 @@ asDWORD asCAtomic::get() const
{
// A very high ref count is highly unlikely. It most likely a problem with
// memory that has been overwritten or is being accessed after it was deleted.
asASSERT(value < MAX_VALUE);
asASSERT(value < 1000000);
return value;
}
@@ -57,7 +56,7 @@ void asCAtomic::set(asDWORD val)
{
// A very high ref count is highly unlikely. It most likely a problem with
// memory that has been overwritten or is being accessed after it was deleted.
asASSERT(value < MAX_VALUE);
asASSERT(value < 1000000);
value = val;
}
@@ -66,7 +65,7 @@ asDWORD asCAtomic::atomicInc()
{
// A very high ref count is highly unlikely. It most likely a problem with
// memory that has been overwritten or is being accessed after it was deleted.
asASSERT(value < MAX_VALUE);
asASSERT(value < 1000000);
return asAtomicInc((int&)value);
}
@@ -75,7 +74,7 @@ asDWORD asCAtomic::atomicDec()
{
// A very high ref count is highly unlikely. It most likely a problem with
// memory that has been overwritten or is being accessed after it was deleted.
asASSERT(value < MAX_VALUE);
asASSERT(value < 1000000);
return asAtomicDec((int&)value);
}

View File

@@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2020 Andreas Jonsson
Copyright (c) 2003-2021 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
@@ -1602,8 +1602,29 @@ int asCBuilder::CheckNameConflict(const char *name, asCScriptNode *node, asCScri
}
#ifndef AS_NO_COMPILER
// Check against class types
// Check against interface types
asUINT n;
for (n = 0; n < interfaceDeclarations.GetLength(); n++)
{
if (interfaceDeclarations[n]->name == name &&
interfaceDeclarations[n]->typeInfo->nameSpace == ns)
{
if (code)
{
asCString str;
if (ns->name != "")
str = ns->name + "::" + name;
else
str = name;
str.Format(TXT_NAME_CONFLICT_s_INTF, str.AddressOf());
WriteError(str, code, node);
}
return -1;
}
}
// Check against class types
for( n = 0; n < classDeclarations.GetLength(); n++ )
{
if( classDeclarations[n]->name == name &&
@@ -2080,10 +2101,12 @@ int asCBuilder::RegisterMixinClass(asCScriptNode *node, asCScriptCode *file, asS
asCScriptNode *n = cl->firstChild;
// Skip potential 'final' and 'shared' tokens
// Skip potential decorator tokens
while( n->tokenType == ttIdentifier &&
(file->TokenEquals(n->tokenPos, n->tokenLength, FINAL_TOKEN) ||
file->TokenEquals(n->tokenPos, n->tokenLength, SHARED_TOKEN)) )
file->TokenEquals(n->tokenPos, n->tokenLength, SHARED_TOKEN) ||
file->TokenEquals(n->tokenPos, n->tokenLength, ABSTRACT_TOKEN) ||
file->TokenEquals(n->tokenPos, n->tokenLength, EXTERNAL_TOKEN)) )
{
// Report error, because mixin class cannot be final or shared
asCString msg;
@@ -2921,7 +2944,8 @@ void asCBuilder::CompileInterfaces()
// If any of the derived interfaces are found after this interface, then move this to the end of the list
for( asUINT m = n+1; m < interfaceDeclarations.GetLength(); m++ )
{
if( intfType->Implements(interfaceDeclarations[m]->typeInfo) )
if( intfType != interfaceDeclarations[m]->typeInfo &&
intfType->Implements(interfaceDeclarations[m]->typeInfo) )
{
interfaceDeclarations.RemoveIndex(n);
interfaceDeclarations.PushLast(intfDecl);
@@ -4762,7 +4786,7 @@ int asCBuilder::RegisterScriptFunctionFromNode(asCScriptNode *node, asCScriptCod
return RegisterScriptFunction(node, file, objType, isInterface, isGlobalFunction, ns, isExistingShared, isMixin, name, returnType, parameterNames, parameterTypes, inOutFlags, defaultArgs, funcTraits);
}
asCScriptFunction *asCBuilder::RegisterLambda(asCScriptNode *node, asCScriptCode *file, asCScriptFunction *funcDef, const asCString &name, asSNameSpace *ns)
asCScriptFunction *asCBuilder::RegisterLambda(asCScriptNode *node, asCScriptCode *file, asCScriptFunction *funcDef, const asCString &name, asSNameSpace *ns, bool isShared)
{
// Get the parameter names from the node
asCArray<asCString> parameterNames;
@@ -4785,7 +4809,9 @@ asCScriptFunction *asCBuilder::RegisterLambda(asCScriptNode *node, asCScriptCode
// Get the return and parameter types from the funcDef
asCString funcName = name;
int r = RegisterScriptFunction(args, file, 0, 0, true, ns, false, false, funcName, funcDef->returnType, parameterNames, funcDef->parameterTypes, funcDef->inOutFlags, defaultArgs, asSFunctionTraits());
asSFunctionTraits traits;
traits.SetTrait(asTRAIT_SHARED, isShared);
int r = RegisterScriptFunction(args, file, 0, 0, true, ns, false, false, funcName, funcDef->returnType, parameterNames, funcDef->parameterTypes, funcDef->inOutFlags, defaultArgs, traits);
if( r < 0 )
return 0;
@@ -5470,7 +5496,7 @@ void asCBuilder::GetObjectMethodDescriptions(const char *name, asCObjectType *ob
// TODO: child funcdef: A scope can include a template type, e.g. array<ns::type>
int n = scope.FindLast("::");
asCString className = n >= 0 ? scope.SubString(n+2) : scope;
asCString nsName = n >= 0 ? scope.SubString(0, n) : "";
asCString nsName = n >= 0 ? scope.SubString(0, n) : asCString("");
// If a namespace was specifically defined, then this must be used
asSNameSpace *ns = 0;
@@ -5954,6 +5980,19 @@ asCDataType asCBuilder::CreateDataTypeFromNode(asCScriptNode *node, asCScriptCod
{
if( n->tokenType == ttOpenBracket )
{
if (isImplicitHandle)
{
// Make the type a handle
if (dt.MakeHandle(true, acceptHandleForScope) < 0)
{
if (reportError)
WriteError(TXT_OBJECT_HANDLE_NOT_SUPPORTED, file, n);
if (isValid)
*isValid = false;
}
isImplicitHandle = false;
}
// Make sure the sub type can be instantiated
if( !dt.CanBeInstantiated() )
{

View File

@@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2019 Andreas Jonsson
Copyright (c) 2003-2021 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
@@ -217,7 +217,7 @@ protected:
int RegisterEnum(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
int RegisterTypedef(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
int RegisterFuncDef(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns, asCObjectType *parent);
asCScriptFunction *RegisterLambda(asCScriptNode *node, asCScriptCode *file, asCScriptFunction *funcDef, const asCString &name, asSNameSpace *ns);
asCScriptFunction *RegisterLambda(asCScriptNode *node, asCScriptCode *file, asCScriptFunction *funcDef, const asCString &name, asSNameSpace *ns, bool isShared);
void CompleteFuncDef(sFuncDef *funcDef);
void CompileInterfaces();
void CompileClasses(asUINT originalNumTempl);

View File

@@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2020 Andreas Jonsson
Copyright (c) 2003-2021 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
@@ -55,8 +55,7 @@ BEGIN_AS_NAMESPACE
int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv, void *auxiliary, asSSystemFunctionInterface *internal)
{
memset(internal, 0, sizeof(asSSystemFunctionInterface));
internal->Clear();
internal->func = ptr.ptr.f.func;
internal->auxiliary = 0;

View File

@@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2020 Andreas Jonsson
Copyright (c) 2003-2021 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
@@ -119,13 +119,35 @@ struct asSSystemFunctionInterface
};
asCArray<SClean> cleanArgs;
asSSystemFunctionInterface() : func(0), baseOffset(0), callConv(ICC_GENERIC_FUNC), hostReturnInMemory(false), hostReturnFloat(false), hostReturnSize(0), paramSize(0), takesObjByVal(false), returnAutoHandle(false), compositeOffset(0), isCompositeIndirect(false), auxiliary(0) {}
asSSystemFunctionInterface()
{
Clear();
}
asSSystemFunctionInterface(const asSSystemFunctionInterface &in)
{
*this = in;
}
void Clear()
{
func = 0;
baseOffset = 0;
callConv = ICC_GENERIC_FUNC;
hostReturnInMemory = false;
hostReturnFloat = false;
hostReturnSize = 0;
paramSize = 0;
takesObjByVal = false;
returnAutoHandle = false;
compositeOffset = 0;
isCompositeIndirect = false;
auxiliary = 0;
paramAutoHandles.SetLength(0);
cleanArgs.SetLength(0);
}
asSSystemFunctionInterface &operator=(const asSSystemFunctionInterface &in)
{
func = in.func;
@@ -136,12 +158,14 @@ struct asSSystemFunctionInterface
hostReturnSize = in.hostReturnSize;
paramSize = in.paramSize;
takesObjByVal = in.takesObjByVal;
paramAutoHandles = in.paramAutoHandles;
returnAutoHandle = in.returnAutoHandle;
compositeOffset = in.compositeOffset;
isCompositeIndirect = in.isCompositeIndirect;
auxiliary = in.auxiliary;
cleanArgs = in.cleanArgs;
paramAutoHandles = in.paramAutoHandles;
return *this;
}
};

View File

@@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2020-2020 Andreas Jonsson
Copyright (c) 2020-2021 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
@@ -110,7 +110,7 @@ static inline bool IsRegisterHFA(const asCDataType &type)
if( typeInfo == nullptr ||
(typeInfo->flags & asOBJ_APP_CLASS_ALLFLOATS) == 0 ||
type.IsObjectHandle() && type.IsReference() )
type.IsObjectHandle() || type.IsReference() )
return false;
const bool doubles = (typeInfo->flags & asOBJ_APP_CLASS_ALIGN8) != 0;

View File

@@ -1,6 +1,6 @@
//
// AngelCode Scripting Library
// Copyright (c) 2020-2020 Andreas Jonsson
// Copyright (c) 2020-2021 Andreas Jonsson
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any
@@ -35,6 +35,10 @@
// Compile with GCC/GAS
#if !defined(AS_MAX_PORTABILITY)
#if defined(__aarch64__)
.arch armv8-a
.text
@@ -217,3 +221,7 @@ CallARM64RetInMemory:
.cfi_def_cfa_offset 0
ret
.cfi_endproc
#endif /* __aarch64__ */
#endif /* !AS_MAX_PORTABILITY */

View File

@@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2020 Andreas Jonsson
Copyright (c) 2003-2021 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
@@ -1513,7 +1513,8 @@ int asCCompiler::PrepareArgument(asCDataType *paramType, asCExprContext *ctx, as
else if( ctx->type.dataType.IsNullHandle() )
{
// Make sure the argument type can support handles (or is itself a handle)
if( !dt.SupportHandles() && !dt.IsObjectHandle() )
// Don't allow null handle to be converted to an object type of ASHANDLE here, that would require more logic to call the constructor (which should be handled in ImplicitConversion)
if( (!dt.SupportHandles() && !dt.IsObjectHandle()) || (dt.GetTypeInfo() && (dt.GetTypeInfo()->GetFlags() & asOBJ_ASHANDLE)) )
{
asCString str;
str.Format(TXT_CANT_IMPLICITLY_CONVERT_s_TO_s, ctx->type.dataType.Format(outFunc->nameSpace).AddressOf(), param.Format(outFunc->nameSpace).AddressOf());
@@ -2696,7 +2697,6 @@ bool asCCompiler::CompileAutoType(asCDataType &type, asCExprContext &compiledCtx
// For types that support handles auto should prefer handle
// as it is more efficient than making a copy
// TODO: 'auto a = ...;' and 'auto @a = ...;' works the same in this case. Is this what we want?
if( newType.SupportHandles() )
newType.MakeHandle(true);
@@ -3163,7 +3163,7 @@ bool asCCompiler::CompileInitialization(asCScriptNode *node, asCByteCode *bc, co
}
else
{
// Call the default constructur, then call the assignment operator
// Call the default constructor, then call the assignment operator
asCExprContext ctx(engine);
// Call the default constructor here
@@ -3812,7 +3812,7 @@ int asCCompiler::CompileInitListElement(asSListPatternNode *&patternNode, asCScr
asCExprContext ctx(engine);
DoAssignment(&ctx, &lctx, &rctx, valueNode, valueNode, ttAssignment, valueNode);
if( !lctx.type.dataType.IsPrimitive() )
if( !ctx.type.dataType.IsPrimitive() )
ctx.bc.Instr(asBC_PopPtr);
// Release temporary variables used by expression
@@ -3904,7 +3904,7 @@ int asCCompiler::CompileInitListElement(asSListPatternNode *&patternNode, asCScr
asCExprContext ctx(engine);
DoAssignment(&ctx, &lctx, &rctx, valueNode, valueNode, ttAssignment, valueNode);
if( !lctx.type.dataType.IsPrimitive() )
if( !ctx.type.dataType.IsPrimitive() )
ctx.bc.Instr(asBC_PopPtr);
// Release temporary variables used by expression
@@ -4855,7 +4855,7 @@ void asCCompiler::PrepareTemporaryVariable(asCScriptNode *node, asCExprContext *
{
ctx->bc.Instr(asBC_PopPtr);
ctx->bc.InstrSHORT(asBC_PSF, ctx->type.stackOffset);
ctx->type.dataType.MakeReference(true);
ctx->type.dataType.MakeReference(IsVariableOnHeap(ctx->type.stackOffset));
}
return;
@@ -5273,7 +5273,7 @@ int asCCompiler::AllocateVariable(const asCDataType &type, bool isTemporary, boo
bool isOnHeap = true;
if( t.IsPrimitive() ||
(t.GetTypeInfo() && (t.GetTypeInfo()->GetFlags() & asOBJ_VALUE) && !forceOnHeap) )
(t.GetTypeInfo() && (t.GetTypeInfo()->GetFlags() & asOBJ_VALUE) && !forceOnHeap && !asReference) )
{
// Primitives and value types (unless overridden) are allocated on the stack
isOnHeap = false;
@@ -6106,7 +6106,7 @@ asUINT asCCompiler::ImplicitConvPrimitiveToPrimitive(asCExprContext *ctx, const
// Start by implicitly converting constant values
if( ctx->type.isConstant )
{
ImplicitConversionConstant(ctx, to, node, convType);
ImplicitConversionConstant(ctx, to, generateCode ? node : 0, convType);
ctx->type.dataType.MakeReadOnly(to.IsReadOnly());
return cost;
}
@@ -6482,7 +6482,7 @@ asUINT asCCompiler::ImplicitConvLambdaToFunc(asCExprContext *ctx, const asCDataT
name.Format("$%s$%d", outFunc->GetDeclaration(), numLambdas++);
// Register the lambda with the builder for later compilation
asCScriptFunction *func = builder->RegisterLambda(ctx->exprNode, script, funcDef, name, outFunc->nameSpace);
asCScriptFunction *func = builder->RegisterLambda(ctx->exprNode, script, funcDef, name, outFunc->nameSpace, outFunc->IsShared());
asASSERT( func == 0 || funcDef->IsSignatureExceptNameEqual(func) );
ctx->bc.InstrPTR(asBC_FuncPtr, func);
@@ -7174,12 +7174,23 @@ asUINT asCCompiler::ImplicitConvObjectToObject(asCExprContext *ctx, const asCDat
asUINT cost = ImplicitConvObjectRef(ctx, to, node, convType, generateCode);
// If the desired type is an asOBJ_ASHANDLE then we'll assume it is allowed to implicitly
// construct the object through any of the available constructors
// construct the object through any of the available constructors (except those marked as explicit)
if( to.GetTypeInfo() && (to.GetTypeInfo()->flags & asOBJ_ASHANDLE) && to.GetTypeInfo() != ctx->type.dataType.GetTypeInfo() && allowObjectConstruct )
{
asCArray<int> funcs;
funcs = CastToObjectType(to.GetTypeInfo())->beh.constructors;
// Don't allow use of explicit constructors/factories in implicit conversions
if (convType == asIC_IMPLICIT_CONV)
{
for (asUINT n = 0; n < funcs.GetLength(); n++)
{
asCScriptFunction* desc = builder->GetFunctionDescription(funcs[n]);
if (desc->IsExplicit())
funcs.RemoveIndex(n--);
}
}
asCArray<asCExprContext *> args;
args.PushLast(ctx);
@@ -8049,17 +8060,28 @@ void asCCompiler::ImplicitConversionConstant(asCExprContext *from, const asCData
// Verify if it is possible
if( to.GetSizeInMemoryBytes() == 1 )
{
if( asBYTE(from->type.GetConstantDW()) != from->type.GetConstantDW() )
if( (from->type.dataType.GetSizeInMemoryBytes() == 2 && asBYTE(from->type.GetConstantW()) != from->type.GetConstantW()) ||
(from->type.dataType.GetSizeInMemoryBytes() == 4 && asBYTE(from->type.GetConstantDW()) != from->type.GetConstantDW()) ||
(from->type.dataType.GetSizeInMemoryBytes() == 8 && asBYTE(from->type.GetConstantQW()) != from->type.GetConstantQW()) )
if( convType != asIC_EXPLICIT_VAL_CAST && node ) Warning(TXT_VALUE_TOO_LARGE_FOR_TYPE, node);
from->type.SetConstantB(asCDataType::CreatePrimitive(to.GetTokenType(), true), asBYTE(from->type.GetConstantDW()));
if( from->type.dataType.GetSizeInMemoryBytes() == 2 )
from->type.SetConstantB(asCDataType::CreatePrimitive(to.GetTokenType(), true), asBYTE(from->type.GetConstantW()));
else if (from->type.dataType.GetSizeInMemoryBytes() == 4)
from->type.SetConstantB(asCDataType::CreatePrimitive(to.GetTokenType(), true), asBYTE(from->type.GetConstantDW()));
else if (from->type.dataType.GetSizeInMemoryBytes() == 8)
from->type.SetConstantB(asCDataType::CreatePrimitive(to.GetTokenType(), true), asBYTE(from->type.GetConstantQW()));
}
else if( to.GetSizeInMemoryBytes() == 2 )
{
if( asWORD(from->type.GetConstantDW()) != from->type.GetConstantDW())
if( (from->type.dataType.GetSizeInMemoryBytes() == 4 && asWORD(from->type.GetConstantDW()) != from->type.GetConstantDW()) ||
(from->type.dataType.GetSizeInMemoryBytes() == 8 && asWORD(from->type.GetConstantQW()) != from->type.GetConstantQW()) )
if( convType != asIC_EXPLICIT_VAL_CAST && node ) Warning(TXT_VALUE_TOO_LARGE_FOR_TYPE, node);
from->type.SetConstantW(asCDataType::CreatePrimitive(to.GetTokenType(), true), asWORD(from->type.GetConstantDW()));
if (from->type.dataType.GetSizeInMemoryBytes() == 4)
from->type.SetConstantW(asCDataType::CreatePrimitive(to.GetTokenType(), true), asWORD(from->type.GetConstantDW()));
else if (from->type.dataType.GetSizeInMemoryBytes() == 8)
from->type.SetConstantW(asCDataType::CreatePrimitive(to.GetTokenType(), true), asWORD(from->type.GetConstantQW()));
}
else if (to.GetSizeInMemoryBytes() == 4)
{
@@ -8650,7 +8672,7 @@ int asCCompiler::CompileCondition(asCScriptNode *expr, asCExprContext *ctx)
{
Error(TXT_EXPR_MUST_BE_BOOL, cexpr);
e.type.SetConstantB(asCDataType::CreatePrimitive(ttBool, true), true);
}
}
ctype = e.type;
if( ProcessPropertyGetAccessor(&e, cexpr) < 0)
@@ -8673,44 +8695,22 @@ int asCCompiler::CompileCondition(asCScriptNode *expr, asCExprContext *ctx)
int rr = CompileAssignment(cexpr->next->next, &re);
DetermineSingleFunc(&re, cexpr->next->next);
if( lr >= 0 && rr >= 0 )
if (lr >= 0 && rr >= 0)
{
// Don't allow any operators on expressions that take address of class method
if( le.IsClassMethod() || re.IsClassMethod() )
if (le.IsClassMethod() || re.IsClassMethod())
{
Error(TXT_INVALID_OP_ON_METHOD, expr);
return -1;
}
if( ProcessPropertyGetAccessor(&le, cexpr->next) < 0 )
if (ProcessPropertyGetAccessor(&le, cexpr->next) < 0)
return -1;
if( ProcessPropertyGetAccessor(&re, cexpr->next->next) < 0 )
if (ProcessPropertyGetAccessor(&re, cexpr->next->next) < 0)
return -1;
bool isExplicitHandle = le.type.isExplicitHandle || re.type.isExplicitHandle;
// Allow a 0 or null in the first case to be implicitly converted to the second type
if( le.type.isConstant && le.type.GetConstantData() == 0 && le.type.dataType.IsIntegerType() )
{
asCDataType to = re.type.dataType;
to.MakeReference(false);
to.MakeReadOnly(true);
ImplicitConversionConstant(&le, to, cexpr->next, asIC_IMPLICIT_CONV);
}
else if( le.type.IsNullConstant() )
{
asCDataType to = re.type.dataType;
to.MakeHandle(true);
ImplicitConversion(&le, to, cexpr->next, asIC_IMPLICIT_CONV);
}
// Allow either case to be converted to const @ if the other is const @
if( (le.type.dataType.IsHandleToConst() && !le.type.IsNullConstant()) || (re.type.dataType.IsHandleToConst() && !re.type.dataType.IsNullHandle()) )
{
le.type.dataType.MakeHandleToConst(true);
re.type.dataType.MakeHandleToConst(true);
}
// Allow an anonymous initialization list to be converted to the type in the other condition
if (le.IsAnonymousInitList() && re.type.dataType.GetBehaviour() && re.type.dataType.GetBehaviour()->listFactory)
{
@@ -8727,7 +8727,7 @@ int asCCompiler::CompileCondition(asCScriptNode *expr, asCExprContext *ctx)
ImplicitConversion(&re, to, cexpr->next->next, asIC_IMPLICIT_CONV);
}
if (le.IsAnonymousInitList() )
if (le.IsAnonymousInitList())
{
Error(TXT_CANNOT_RESOLVE_AUTO, cexpr->next);
return -1;
@@ -8738,6 +8738,81 @@ int asCCompiler::CompileCondition(asCScriptNode *expr, asCExprContext *ctx)
return -1;
}
// Try to perform an implicit cast to make the two operands of the same type
// Choose the conversion that is the least costly
if (le.type.dataType != re.type.dataType)
{
asCExprContext tmp(engine);
tmp.type = le.type;
tmp.type.dataType.MakeReference(false);
asUINT costAtoB = ImplicitConversion(&tmp, re.type.dataType, cexpr->next, asIC_IMPLICIT_CONV, false);
if (!tmp.type.dataType.IsEqualExceptRef(re.type.dataType))
costAtoB = 0xFFFFFFFF;
tmp.type = re.type;
tmp.type.dataType.MakeReference(false);
asUINT costBtoA = ImplicitConversion(&tmp, le.type.dataType, cexpr->next->next, asIC_IMPLICIT_CONV, false);
if (!tmp.type.dataType.IsEqualExceptRef(le.type.dataType))
costBtoA = 0xFFFFFFFF;
if (costAtoB < costBtoA && costAtoB != 0xFFFFFFFF)
{
Dereference(&le, true);
ImplicitConversion(&le, re.type.dataType, cexpr->next, asIC_IMPLICIT_CONV, true);
}
else if (costAtoB > costBtoA && costBtoA != 0xFFFFFFFF)
{
Dereference(&re, true);
ImplicitConversion(&re, le.type.dataType, cexpr->next->next, asIC_IMPLICIT_CONV, true);
}
// If the cost for conversion is the same in both directions we have an ambigious situation,
// which we do not resolve. In that case the script need to perform an explicit conversion
}
// Allow a 0 to be implicitly converted to the other type
if (le.type.isConstant && le.type.GetConstantData() == 0 && le.type.dataType.IsIntegerType())
{
asCDataType to = re.type.dataType;
to.MakeReference(false);
to.MakeReadOnly(true);
ImplicitConversionConstant(&le, to, cexpr->next, asIC_IMPLICIT_CONV);
}
else if( re.type.isConstant && re.type.GetConstantData() == 0 && re.type.dataType.IsIntegerType())
{
asCDataType to = le.type.dataType;
to.MakeReference(false);
to.MakeReadOnly(true);
ImplicitConversionConstant(&re, to, cexpr->next->next, asIC_IMPLICIT_CONV);
}
// Allow expression to be converted to handle if the other is handle
if (!le.type.dataType.IsObjectHandle() && re.type.dataType.IsObjectHandle() && le.type.dataType.GetTypeInfo() == re.type.dataType.GetTypeInfo() )
{
asCDataType dt = le.type.dataType;
dt.MakeHandle(true);
ImplicitConversion(&le, dt, cexpr->next, asIC_IMPLICIT_CONV);
}
if (!re.type.dataType.IsObjectHandle() && le.type.dataType.IsObjectHandle() && le.type.dataType.GetTypeInfo() == re.type.dataType.GetTypeInfo())
{
asCDataType dt = re.type.dataType;
dt.MakeHandle(true);
ImplicitConversion(&re, dt, cexpr->next->next, asIC_IMPLICIT_CONV);
}
// Allow either case to be converted to const @ if the other is const @
if( (le.type.dataType.IsHandleToConst() && !le.type.IsNullConstant()) || (re.type.dataType.IsHandleToConst() && !re.type.dataType.IsNullHandle()) )
{
le.type.dataType.MakeHandleToConst(true);
re.type.dataType.MakeHandleToConst(true);
}
// Make sure both expressions have the same type
if (!le.type.dataType.IsEqualExceptRefAndConst(re.type.dataType))
{
Error(TXT_BOTH_MUST_BE_SAME, expr);
return -1;
}
//---------------------------------
// Output the byte code
int afterLabel = nextLabel++;
@@ -8766,10 +8841,6 @@ int asCCompiler::CompileCondition(asCScriptNode *expr, asCExprContext *ctx)
MergeExprBytecode(ctx, &re);
ctx->bc.Label((short)afterLabel);
// Make sure both expressions have the same type
if( le.type.dataType != re.type.dataType )
Error(TXT_BOTH_MUST_BE_SAME, expr);
// Set the type of the result
ctx->type = le.type;
}
@@ -8810,7 +8881,7 @@ int asCCompiler::CompileCondition(asCScriptNode *expr, asCExprContext *ctx)
// with a stack offset (i.e. it will not be allowed to use asBC_VAR)
if( le.type.isLValue && re.type.isLValue &&
le.deferredParams.GetLength() == 0 && re.deferredParams.GetLength() ==0 &&
le.deferredParams.GetLength() == 0 && re.deferredParams.GetLength() == 0 &&
!le.type.isTemporary && !re.type.isTemporary &&
le.type.dataType == re.type.dataType )
{
@@ -8928,6 +8999,9 @@ int asCCompiler::CompileCondition(asCScriptNode *expr, asCExprContext *ctx)
// Release the old temporary variable
ReleaseTemporaryVariable(le.type, &ctx->bc);
// Process any deferred arguments in the expressions as these must not survive until after the condition returns
ProcessDeferredParams(ctx);
ctx->bc.InstrINT(asBC_JMP, afterLabel);
// Start of the right expression
@@ -8950,11 +9024,10 @@ int asCCompiler::CompileCondition(asCScriptNode *expr, asCExprContext *ctx)
// Release the old temporary variable
ReleaseTemporaryVariable(re.type, &ctx->bc);
ctx->bc.Label((short)afterLabel);
// Process any deferred arguments in the expressions as these must not survive until after the condition returns
ProcessDeferredParams(ctx);
// Make sure both expressions have the same type
if( !le.type.dataType.IsEqualExceptConst(re.type.dataType) )
Error(TXT_BOTH_MUST_BE_SAME, expr);
ctx->bc.Label((short)afterLabel);
// Set the temporary variable as output
ctx->type = rtemp;
@@ -9366,7 +9439,7 @@ asCCompiler::SYMBOLTYPE asCCompiler::SymbolLookup(const asCString &name, const a
// TODO: child funcdef: A scope can include a template type, e.g. array<ns::type>
int n = currScope.FindLast("::");
asCString typeName = n >= 0 ? currScope.SubString(n + 2) : currScope;
asCString nsName = n >= 0 ? currScope.SubString(0, n) : "";
asCString nsName = n >= 0 ? currScope.SubString(0, n) : asCString("");
// If the scope represents a type that the current class inherits
// from then that should be used instead of going through the namespaces
@@ -10988,7 +11061,8 @@ int asCCompiler::CompileConstructCall(asCScriptNode *node, asCExprContext *ctx)
if( conv.type.dataType.IsEqualExceptRef(dt) && cost > 0 )
{
// Make sure the result is a reference, just as if to a local variable
dt.MakeReference(true);
if( !dt.IsFuncdef() )
dt.MakeReference(true);
// Make sure any property accessor is already evaluated
if( ProcessPropertyGetAccessor(args[0], args[0]->exprNode) < 0 )

View File

@@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2020 Andreas Jonsson
Copyright (c) 2003-2021 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
@@ -252,26 +252,27 @@
// compiler is the same for both, when this is so these flags are used to produce the
// right code.
// AS_WIN - Microsoft Windows
// AS_LINUX - Linux
// AS_MAC - Apple Macintosh
// AS_BSD - BSD based OS (FreeBSD, DragonFly, OpenBSD, etc)
// AS_XBOX - Microsoft XBox
// AS_XBOX360 - Microsoft XBox 360
// AS_PSP - Sony Playstation Portable
// AS_PSVITA - Sony Playstation Vita
// AS_PS2 - Sony Playstation 2
// AS_PS3 - Sony Playstation 3
// AS_DC - Sega Dreamcast
// AS_GC - Nintendo GameCube
// AS_WII - Nintendo Wii
// AS_WIIU - Nintendo Wii U
// AS_IPHONE - Apple IPhone
// AS_ANDROID - Android
// AS_HAIKU - Haiku
// AS_ILLUMOS - Illumos like (OpenSolaris, OpenIndiana, NCP, etc)
// AS_MARMALADE - Marmalade cross platform SDK (a layer on top of the OS)
// AS_SUN - Sun UNIX
// AS_WIN - Microsoft Windows
// AS_LINUX - Linux
// AS_MAC - Apple Macintosh
// AS_BSD - BSD based OS (FreeBSD, DragonFly, OpenBSD, etc)
// AS_XBOX - Microsoft XBox
// AS_XBOX360 - Microsoft XBox 360
// AS_PSP - Sony Playstation Portable
// AS_PSVITA - Sony Playstation Vita
// AS_PS2 - Sony Playstation 2
// AS_PS3 - Sony Playstation 3
// AS_DC - Sega Dreamcast
// AS_GC - Nintendo GameCube
// AS_WII - Nintendo Wii
// AS_WIIU - Nintendo Wii U
// AS_NINTENDOSWITCH - Nintendo Switch
// AS_IPHONE - Apple IPhone
// AS_ANDROID - Android
// AS_HAIKU - Haiku
// AS_ILLUMOS - Illumos like (OpenSolaris, OpenIndiana, NCP, etc)
// AS_MARMALADE - Marmalade cross platform SDK (a layer on top of the OS)
// AS_SUN - Sun UNIX
@@ -656,6 +657,37 @@
// Native calling conventions are not yet supported
#define AS_MAX_PORTABILITY
// Nintendo Switch
// Note, __SWITCH__ is not an official define in the Nintendo dev kit.
// You need to manually add this to the project when compiling for Switch.
#elif defined(__SWITCH__)
#define AS_NINTENDOSWITCH
#if (!defined(__LP64__))
#error write me
#else
#define AS_ARM64
#undef STDCALL
#define STDCALL
#undef GNU_STYLE_VIRTUAL_METHOD
#undef AS_NO_THISCALL_FUNCTOR_METHOD
#define HAS_128_BIT_PRIMITIVES
#define CDECL_RETURN_SIMPLE_IN_MEMORY
#define STDCALL_RETURN_SIMPLE_IN_MEMORY
#define THISCALL_RETURN_SIMPLE_IN_MEMORY
#undef THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
#undef CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
#undef STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
#define THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 5
#define CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 5
#define STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 5
#endif
// Marmalade is a cross platform SDK. It uses g++ to compile for iOS and Android
#elif defined(__S3E__)
#ifndef AS_MARMALADE
@@ -757,7 +789,7 @@
#undef STDCALL
#define STDCALL
#elif (defined(__arm64__))
#elif (defined(__aarch64__))
// The IPhone 5S+ uses an ARM64 processor
// AngelScript currently doesn't support native calling
@@ -779,7 +811,7 @@
#undef COMPLEX_RETURN_MASK
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
#elif defined(__LP64__) && !defined(__ppc__) && !defined(__PPC__) && !defined(__arm64__)
#elif defined(__LP64__) && !defined(__ppc__) && !defined(__PPC__) && !defined(__aarch64__)
// http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/LowLevelABI/140-x86-64_Function_Calling_Conventions/x86_64.html#//apple_ref/doc/uid/TP40005035-SW1
#define AS_X64_GCC
#undef AS_NO_THISCALL_FUNCTOR_METHOD
@@ -1091,30 +1123,40 @@
#undef COMPLEX_RETURN_MASK
#define COMPLEX_RETURN_MASK (asOBJ_APP_CLASS_DESTRUCTOR | asOBJ_APP_CLASS_COPY_CONSTRUCTOR | asOBJ_APP_ARRAY)
#if (defined(_ARM_) || defined(__arm__))
#if (defined(_ARM_) || defined(__arm__) || defined(__aarch64__) || defined(__AARCH64EL__))
// Android ARM
// TODO: The stack unwind on exceptions currently fails due to the assembler code in as_callfunc_arm_gcc.S
#define AS_NO_EXCEPTIONS
#undef THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
#undef CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
#undef STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE
#define THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
#define CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
#define STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
// The stdcall calling convention is not used on the arm cpu
#undef STDCALL
#define STDCALL
#undef GNU_STYLE_VIRTUAL_METHOD
#define AS_ARM
#undef AS_NO_THISCALL_FUNCTOR_METHOD
#define AS_SOFTFP
#define AS_CALLEE_DESTROY_OBJ_BY_VAL
#if (!defined(__LP64__))
// TODO: The stack unwind on exceptions currently fails due to the assembler code in as_callfunc_arm_gcc.S
#define AS_NO_EXCEPTIONS
#define THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
#define CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
#define STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 2
#define AS_ARM
#define AS_SOFTFP
#define AS_CALLEE_DESTROY_OBJ_BY_VAL
#elif (defined(__LP64__) || defined(__aarch64__))
#define AS_ARM64
#define HAS_128_BIT_PRIMITIVES
#define THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 5
#define CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 5
#define STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE 5
#endif
#elif (defined(i386) || defined(__i386) || defined(__i386__)) && !defined(__LP64__)
// Android Intel x86 (same config as Linux x86). Tested with Intel x86 Atom System Image.

View File

@@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2020 Andreas Jonsson
Copyright (c) 2003-2021 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
@@ -2882,7 +2882,8 @@ void asCContext::ExecuteNext()
m_regs.stackPointer = l_sp;
m_regs.stackFramePointer = l_fp;
if( !(objType->flags & asOBJ_NOCOUNT) )
// Update ref counter for object types that require it
if( !(objType->flags & (asOBJ_NOCOUNT | asOBJ_VALUE)) )
{
// Release previous object held by destination pointer
if( *d != 0 && beh->release )
@@ -3912,21 +3913,21 @@ void asCContext::ExecuteNext()
}
else
{
if( func->funcType == asFUNC_SCRIPT )
if (func->funcType == asFUNC_SCRIPT)
{
m_regs.programPointer++;
CallScriptFunction(func);
}
else if( func->funcType == asFUNC_DELEGATE )
else if (func->funcType == asFUNC_DELEGATE)
{
// Push the object pointer on the stack. There is always a reserved space for this so
// we don't don't need to worry about overflowing the allocated memory buffer
asASSERT( m_regs.stackPointer - AS_PTR_SIZE >= m_stackBlocks[m_stackIndex] );
asASSERT(m_regs.stackPointer - AS_PTR_SIZE >= m_stackBlocks[m_stackIndex]);
m_regs.stackPointer -= AS_PTR_SIZE;
*(asPWORD*)m_regs.stackPointer = asPWORD(func->objForDelegate);
// Call the delegated method
if( func->funcForDelegate->funcType == asFUNC_SYSTEM )
if (func->funcForDelegate->funcType == asFUNC_SYSTEM)
{
m_regs.stackPointer += CallSystemFunction(func->funcForDelegate->id, this);
@@ -3942,16 +3943,33 @@ void asCContext::ExecuteNext()
CallInterfaceMethod(func->funcForDelegate);
}
}
else
else if (func->funcType == asFUNC_SYSTEM)
{
asASSERT( func->funcType == asFUNC_SYSTEM );
m_regs.stackPointer += CallSystemFunction(func->id, this);
// Update program position after the call so the line number
// is correct in case the system function queries it
m_regs.programPointer++;
}
else if (func->funcType == asFUNC_IMPORTED)
{
m_regs.programPointer++;
int funcId = m_engine->importedFunctions[func->id & ~FUNC_IMPORTED]->boundFunctionId;
if (funcId > 0)
CallScriptFunction(m_engine->scriptFunctions[funcId]);
else
{
// Tell the exception handler to clean up the arguments to this method
m_needToCleanupArgs = true;
SetInternalException(TXT_UNBOUND_FUNCTION);
}
}
else
{
// Should not get here
asASSERT(false);
}
}
// Extract the values from the context again
@@ -4141,7 +4159,8 @@ void asCContext::ExecuteNext()
m_regs.stackPointer = l_sp;
m_regs.stackFramePointer = l_fp;
if( !(objType->flags & asOBJ_NOCOUNT) )
// Update ref counter for object types that require it
if( !(objType->flags & (asOBJ_NOCOUNT | asOBJ_VALUE)) )
{
// Release previous object held by destination pointer
if( *d != 0 && beh->release )

View File

@@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2020 Andreas Jonsson
Copyright (c) 2003-2021 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
@@ -1470,7 +1470,8 @@ const char *asCModule::GetImportedFunctionDeclaration(asUINT index) const
if( func == 0 ) return 0;
asCString *tempString = &asCThreadManager::GetLocalData()->string;
*tempString = func->GetDeclarationStr();
// TODO: Allow the application to decide if the parameter name should be included or not (requires change in the interface)
*tempString = func->GetDeclarationStr(true, true, false);
return tempString->AddressOf();
}
@@ -1536,28 +1537,28 @@ int asCModule::UnbindAllImportedFunctions()
void asCModule::AddClassType(asCObjectType* type)
{
m_classTypes.PushLast(type);
m_typeLookup.Insert({type->nameSpace, type->name}, type);
m_typeLookup.Insert(asSNameSpaceNamePair(type->nameSpace, type->name), type);
}
// internal
void asCModule::AddEnumType(asCEnumType* type)
{
m_enumTypes.PushLast(type);
m_typeLookup.Insert({type->nameSpace, type->name}, type);
m_typeLookup.Insert(asSNameSpaceNamePair(type->nameSpace, type->name), type);
}
// internal
void asCModule::AddTypeDef(asCTypedefType* type)
{
m_typeDefs.PushLast(type);
m_typeLookup.Insert({type->nameSpace, type->name}, type);
m_typeLookup.Insert(asSNameSpaceNamePair(type->nameSpace, type->name), type);
}
// internal
void asCModule::AddFuncDef(asCFuncdefType* type)
{
m_funcDefs.PushLast(type);
m_typeLookup.Insert({type->nameSpace, type->name}, type);
m_typeLookup.Insert(asSNameSpaceNamePair(type->nameSpace, type->name), type);
}
// internal
@@ -1569,8 +1570,8 @@ void asCModule::ReplaceFuncDef(asCFuncdefType* type, asCFuncdefType* newType)
m_funcDefs[i] = newType;
// Replace it in the lookup map too
asSMapNode<asSNameSpaceNamePair, asCTypeInfo*>* result = nullptr;
if(m_typeLookup.MoveTo(&result, {type->nameSpace, type->name}))
asSMapNode<asSNameSpaceNamePair, asCTypeInfo*>* result = 0;
if(m_typeLookup.MoveTo(&result, asSNameSpaceNamePair(type->nameSpace, type->name)))
{
asASSERT( result->value == type );
result->value = newType;
@@ -1581,8 +1582,8 @@ void asCModule::ReplaceFuncDef(asCFuncdefType* type, asCFuncdefType* newType)
// internal
asCTypeInfo *asCModule::GetType(const asCString &type, asSNameSpace *ns) const
{
asSMapNode<asSNameSpaceNamePair, asCTypeInfo*>* result = nullptr;
if(m_typeLookup.MoveTo(&result, {ns, type}))
asSMapNode<asSNameSpaceNamePair, asCTypeInfo*>* result = 0;
if(m_typeLookup.MoveTo(&result, asSNameSpaceNamePair(ns, type)))
{
return result->value;
}
@@ -1592,8 +1593,8 @@ asCTypeInfo *asCModule::GetType(const asCString &type, asSNameSpace *ns) const
// internal
asCObjectType *asCModule::GetObjectType(const char *type, asSNameSpace *ns) const
{
asSMapNode<asSNameSpaceNamePair, asCTypeInfo*>* result = nullptr;
if(m_typeLookup.MoveTo(&result, {ns, type}))
asSMapNode<asSNameSpaceNamePair, asCTypeInfo*>* result = 0;
if(m_typeLookup.MoveTo(&result, asSNameSpaceNamePair(ns, type)))
{
return CastToObjectType(result->value);
}
@@ -1759,11 +1760,11 @@ int asCModule::CompileGlobalVar(const char *sectionName, const char *code, int l
}
// interface
int asCModule::CompileFunction(const char *sectionName, const char *code, int lineOffset, asDWORD compileFlags, asIScriptFunction **outFunc)
int asCModule::CompileFunction(const char* sectionName, const char* code, int lineOffset, asDWORD compileFlags, asIScriptFunction** outFunc)
{
// Make sure the outFunc is null if the function fails, so the
// application doesn't attempt to release a non-existent function
if( outFunc )
if (outFunc)
*outFunc = 0;
#ifdef AS_NO_COMPILER
@@ -1774,19 +1775,19 @@ int asCModule::CompileFunction(const char *sectionName, const char *code, int li
return asNOT_SUPPORTED;
#else
// Validate arguments
if( code == 0 ||
(compileFlags != 0 && compileFlags != asCOMP_ADD_TO_MODULE) )
if (code == 0 ||
(compileFlags != 0 && compileFlags != asCOMP_ADD_TO_MODULE))
return asINVALID_ARG;
// Only one thread may build at one time
// TODO: It should be possible to have multiple threads perform compilations
int r = m_engine->RequestBuild();
if( r < 0 )
if (r < 0)
return r;
// Prepare the engine
m_engine->PrepareEngine();
if( m_engine->configFailed )
if (m_engine->configFailed)
{
m_engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, TXT_INVALID_CONFIGURATION);
m_engine->BuildCompleted();
@@ -1796,9 +1797,19 @@ int asCModule::CompileFunction(const char *sectionName, const char *code, int li
// Compile the single function
asCBuilder funcBuilder(m_engine, this);
asCString str = code;
asCScriptFunction *func = 0;
asCScriptFunction* func = 0;
r = funcBuilder.CompileFunction(sectionName, str.AddressOf(), lineOffset, compileFlags, &func);
if (r >= 0)
{
// Invoke the JIT compiler if it has been set
asIJITCompiler* jit = m_engine->GetJITCompiler();
if (jit)
{
func->JITCompile();
}
}
m_engine->BuildCompleted();
if( r >= 0 && outFunc && func )

View File

@@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2019 Andreas Jonsson
Copyright (c) 2003-2021 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
@@ -2488,7 +2488,7 @@ asCScriptNode *asCParser::ParseScript(bool inBlock)
UNREACHABLE_RETURN;
}
// BNF:1: NAMESPACE ::= 'namespace' IDENTIFIER '{' SCRIPT '}'
// BNF:1: NAMESPACE ::= 'namespace' IDENTIFIER {'::' IDENTIFIER} '{' SCRIPT '}'
asCScriptNode *asCParser::ParseNamespace()
{
asCScriptNode *node = CreateNode(snNamespace);
@@ -2505,11 +2505,32 @@ asCScriptNode *asCParser::ParseNamespace()
Error(InsteadFound(t1), &t1);
}
// TODO: namespace: Allow declaration of multiple nested namespace with namespace A::B::C { }
node->AddChildLast(ParseIdentifier());
if( isSyntaxError ) return node;
asCScriptNode *lowestNode = node;
GetToken(&t1);
while (t1.type == ttScope)
{
lowestNode->UpdateSourcePos(t1.pos, t1.length);
asCScriptNode *scopeNode = CreateNode(snScript);
if (scopeNode == 0)
return 0;
lowestNode->AddChildLast(scopeNode);
lowestNode = CreateNode(snNamespace);
if (lowestNode == 0)
return 0;
scopeNode->AddChildLast(lowestNode);
lowestNode->AddChildLast(ParseIdentifier());
if (isSyntaxError)
return node;
GetToken(&t1);
}
if( t1.type == ttStartStatementBlock )
node->UpdateSourcePos(t1.pos, t1.length);
else
@@ -2521,7 +2542,7 @@ asCScriptNode *asCParser::ParseNamespace()
sToken start = t1;
node->AddChildLast(ParseScript(true));
lowestNode->AddChildLast(ParseScript(true));
if( !isSyntaxError )
{

View File

@@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2020 Andreas Jonsson
Copyright (c) 2003-2021 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
@@ -155,7 +155,7 @@ int asCReader::ReadInner()
noDebugInfo = ReadEncodedUInt() ? VALUE_OF_BOOLEAN_TRUE : 0;
// Read enums
count = ReadEncodedUInt();
count = SanityCheck(ReadEncodedUInt(), 1000000);
module->m_enumTypes.Allocate(count, false);
for( i = 0; i < count && !error; i++ )
{
@@ -228,7 +228,7 @@ int asCReader::ReadInner()
// classTypes[]
// First restore the structure names, then the properties
count = ReadEncodedUInt();
count = SanityCheck(ReadEncodedUInt(), 1000000);
module->m_classTypes.Allocate(count, false);
for( i = 0; i < count && !error; ++i )
{
@@ -299,7 +299,7 @@ int asCReader::ReadInner()
if( error ) return asERROR;
// Read func defs
count = ReadEncodedUInt();
count = SanityCheck(ReadEncodedUInt(), 1000000);
module->m_funcDefs.Allocate(count, false);
for( i = 0; i < count && !error; i++ )
{
@@ -401,7 +401,7 @@ int asCReader::ReadInner()
if( error ) return asERROR;
// Read typedefs
count = ReadEncodedUInt();
count = SanityCheck(ReadEncodedUInt(), 1000000);
module->m_typeDefs.Allocate(count, false);
for( i = 0; i < count && !error; i++ )
{
@@ -422,7 +422,7 @@ int asCReader::ReadInner()
if( error ) return asERROR;
// scriptGlobals[]
count = ReadEncodedUInt();
count = SanityCheck(ReadEncodedUInt(), 1000000);
if( count && engine->ep.disallowGlobalVars )
{
engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, TXT_GLOBAL_VARS_NOT_ALLOWED);
@@ -435,7 +435,7 @@ int asCReader::ReadInner()
}
// scriptFunctions[]
count = ReadEncodedUInt();
count = SanityCheck(ReadEncodedUInt(), 1000000);
for( i = 0; i < count && !error; ++i )
{
size_t len = module->m_scriptFunctions.GetLength();
@@ -496,7 +496,7 @@ int asCReader::ReadInner()
}
// globalFunctions[]
count = ReadEncodedUInt();
count = SanityCheck(ReadEncodedUInt(), 1000000);
for( i = 0; i < count && !error; ++i )
{
bool isNew;
@@ -516,7 +516,7 @@ int asCReader::ReadInner()
if( error ) return asERROR;
// bindInformations[]
count = ReadEncodedUInt();
count = SanityCheck(ReadEncodedUInt(), 1000000);
module->m_bindInformations.Allocate(count, false);
for( i = 0; i < count && !error; ++i )
{
@@ -554,7 +554,7 @@ int asCReader::ReadInner()
if( error ) return asERROR;
// usedTypes[]
count = ReadEncodedUInt();
count = SanityCheck(ReadEncodedUInt(), 1000000);
usedTypes.Allocate(count, false);
for( i = 0; i < count && !error; ++i )
{
@@ -660,7 +660,7 @@ void asCReader::ReadUsedStringConstants()
asCString str;
asUINT count;
count = ReadEncodedUInt();
count = SanityCheck(ReadEncodedUInt(), 1000000);
if (count > 0 && engine->stringFactory == 0)
{
@@ -681,7 +681,7 @@ void asCReader::ReadUsedFunctions()
TimeIt("asCReader::ReadUsedFunctions");
asUINT count;
count = ReadEncodedUInt();
count = SanityCheck(ReadEncodedUInt(), 1000000);
usedFunctions.SetLength(count);
if( usedFunctions.GetLength() != count )
{
@@ -1026,13 +1026,7 @@ void asCReader::ReadFunctionSignature(asCScriptFunction *func, asCObjectType **p
ReadDataType(&func->returnType);
count = ReadEncodedUInt();
if( count > 256 )
{
// Too many arguments, must be something wrong in the file
Error(TXT_INVALID_BYTECODE_d);
return;
}
count = SanityCheck(ReadEncodedUInt(), 256);
func->parameterTypes.Allocate(count, false);
for( i = 0; i < count; ++i )
{
@@ -1253,12 +1247,12 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
ReadByteCode(func);
func->scriptData->variableSpace = ReadEncodedUInt();
func->scriptData->variableSpace = SanityCheck(ReadEncodedUInt(), 1000000);
func->scriptData->objVariablesOnHeap = 0;
if (bits & 8)
{
count = ReadEncodedUInt();
count = SanityCheck(ReadEncodedUInt(), 1000000);
func->scriptData->objVariablePos.Allocate(count, false);
func->scriptData->objVariableTypes.Allocate(count, false);
for (i = 0; i < count; ++i)
@@ -1275,14 +1269,14 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
}
}
if (count > 0)
func->scriptData->objVariablesOnHeap = ReadEncodedUInt();
func->scriptData->objVariablesOnHeap = SanityCheck(ReadEncodedUInt(), 10000);
int length = ReadEncodedUInt();
int length = SanityCheck(ReadEncodedUInt(), 1000000);
func->scriptData->objVariableInfo.SetLength(length);
for (i = 0; i < length; ++i)
{
func->scriptData->objVariableInfo[i].programPos = ReadEncodedUInt();
func->scriptData->objVariableInfo[i].variableOffset = ReadEncodedUInt();
func->scriptData->objVariableInfo[i].programPos = SanityCheck(ReadEncodedUInt(), 1000000);
func->scriptData->objVariableInfo[i].variableOffset = SanityCheck(ReadEncodedInt(), 10000);
asEObjVarInfoOption option = (asEObjVarInfoOption)ReadEncodedUInt();
func->scriptData->objVariableInfo[i].option = option;
if (option != asOBJ_INIT &&
@@ -1301,19 +1295,19 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
if (bits & 16)
{
// Read info on try/catch blocks
int length = ReadEncodedUInt();
int length = SanityCheck(ReadEncodedUInt(), 1000000);
func->scriptData->tryCatchInfo.SetLength(length);
for (i = 0; i < length; ++i)
{
// The program position must be adjusted to be in number of instructions
func->scriptData->tryCatchInfo[i].tryPos = ReadEncodedUInt();
func->scriptData->tryCatchInfo[i].catchPos = ReadEncodedUInt();
func->scriptData->tryCatchInfo[i].tryPos = SanityCheck(ReadEncodedUInt(), 1000000);
func->scriptData->tryCatchInfo[i].catchPos = SanityCheck(ReadEncodedUInt(), 1000000);
}
}
if (!noDebugInfo)
{
int length = ReadEncodedUInt();
int length = SanityCheck(ReadEncodedUInt(), 1000000);
func->scriptData->lineNumbers.SetLength(length);
if (int(func->scriptData->lineNumbers.GetLength()) != length)
{
@@ -1326,7 +1320,7 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
func->scriptData->lineNumbers[i] = ReadEncodedUInt();
// Read the array of script sections
length = ReadEncodedUInt();
length = SanityCheck(ReadEncodedUInt(), 1000000);
func->scriptData->sectionIdxs.SetLength(length);
if (int(func->scriptData->sectionIdxs.GetLength()) != length)
{
@@ -1351,7 +1345,7 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
// Read the variable information
if (!noDebugInfo)
{
int length = ReadEncodedUInt();
int length = SanityCheck(ReadEncodedUInt(), 1000000);
func->scriptData->variables.Allocate(length, false);
for (i = 0; i < length; i++)
{
@@ -1366,7 +1360,7 @@ asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool a
func->scriptData->variables.PushLast(var);
var->declaredAtProgramPos = ReadEncodedUInt();
var->stackOffset = ReadEncodedUInt();
var->stackOffset = SanityCheck(ReadEncodedInt(),10000);
ReadString(&var->name);
ReadDataType(&var->type);
@@ -1551,7 +1545,7 @@ void asCReader::ReadTypeDeclaration(asCTypeInfo *type, int phase, bool *isExtern
// Read the initial attributes
ReadString(&type->name);
ReadData(&type->flags, 4);
type->size = ReadEncodedUInt();
type->size = SanityCheck(ReadEncodedUInt(), 1000000);
asCString ns;
ReadString(&ns);
type->nameSpace = engine->AddNameSpace(ns.AddressOf());
@@ -1613,7 +1607,7 @@ void asCReader::ReadTypeDeclaration(asCTypeInfo *type, int phase, bool *isExtern
if( type->flags & asOBJ_ENUM )
{
asCEnumType *t = CastToEnumType(type);
int count = ReadEncodedUInt();
int count = SanityCheck(ReadEncodedUInt(), 1000000);
bool sharedExists = existingShared.MoveTo(0, type);
if( !sharedExists )
{
@@ -1695,7 +1689,7 @@ void asCReader::ReadTypeDeclaration(asCTypeInfo *type, int phase, bool *isExtern
}
// interfaces[] / interfaceVFTOffsets[]
int size = ReadEncodedUInt();
int size = SanityCheck(ReadEncodedUInt(), 1000000);
if( sharedExists )
{
for( int n = 0; n < size; n++ )
@@ -1725,7 +1719,7 @@ void asCReader::ReadTypeDeclaration(asCTypeInfo *type, int phase, bool *isExtern
if (!ot->IsInterface())
{
asUINT offset = ReadEncodedUInt();
asUINT offset = SanityCheck(ReadEncodedUInt(), 1000000);
ot->interfaceVFTOffsets.PushLast(offset);
}
}
@@ -1776,7 +1770,7 @@ void asCReader::ReadTypeDeclaration(asCTypeInfo *type, int phase, bool *isExtern
ot->beh.destruct = 0;
}
size = ReadEncodedUInt();
size = SanityCheck(ReadEncodedUInt(), 1000000);
for( int n = 0; n < size; n++ )
{
func = ReadFunction(isNew, !sharedExists, !sharedExists, !sharedExists);
@@ -1880,7 +1874,7 @@ void asCReader::ReadTypeDeclaration(asCTypeInfo *type, int phase, bool *isExtern
}
// methods[]
size = ReadEncodedUInt();
size = SanityCheck(ReadEncodedUInt(), 1000000);
int n;
for( n = 0; n < size; n++ )
{
@@ -1946,7 +1940,7 @@ void asCReader::ReadTypeDeclaration(asCTypeInfo *type, int phase, bool *isExtern
}
// virtualFunctionTable[]
size = ReadEncodedUInt();
size = SanityCheck(ReadEncodedUInt(), 1000000);
for( n = 0; n < size; n++ )
{
bool isNew;
@@ -2011,7 +2005,7 @@ void asCReader::ReadTypeDeclaration(asCTypeInfo *type, int phase, bool *isExtern
asASSERT(ot);
// properties[]
asUINT size = ReadEncodedUInt();
asUINT size = SanityCheck(ReadEncodedUInt(), 1000000);
for( asUINT n = 0; n < size; n++ )
ReadObjectProperty(ot);
}
@@ -2039,10 +2033,15 @@ asUINT asCReader::ReadEncodedUInt()
return asUINT(qw & 0xFFFFFFFFu);
}
int asCReader::ReadEncodedInt()
{
return int(ReadEncodedUInt());
}
asQWORD asCReader::ReadEncodedUInt64()
{
asQWORD i = 0;
asBYTE b;
asBYTE b = 0xFF; // set to 0xFF to better catch if the stream doesn't update the value
ReadData(&b, 1);
bool isNegative = ( b & 0x80 ) ? true : false;
b &= 0x7F;
@@ -2113,9 +2112,35 @@ asQWORD asCReader::ReadEncodedUInt64()
return i;
}
asUINT asCReader::SanityCheck(asUINT val, asUINT max)
{
if (val > max)
{
Error(TXT_INVALID_BYTECODE_d);
// Return 0 as default value
return 0;
}
return val;
}
int asCReader::SanityCheck(int val, asUINT max)
{
if (val > int(max) || val < -int(max))
{
Error(TXT_INVALID_BYTECODE_d);
// Return 0 as default value
return 0;
}
return val;
}
void asCReader::ReadString(asCString* str)
{
asUINT len = ReadEncodedUInt();
asUINT len = SanityCheck(ReadEncodedUInt(), 1000000);
if( len & 1 )
{
asUINT idx = len/2;
@@ -2261,7 +2286,7 @@ asCTypeInfo* asCReader::ReadTypeInfo()
return 0;
}
asUINT numSubTypes = ReadEncodedUInt();
asUINT numSubTypes = SanityCheck(ReadEncodedUInt(), 100);
asCArray<asCDataType> subTypes;
for( asUINT n = 0; n < numSubTypes; n++ )
{
@@ -2422,7 +2447,7 @@ void asCReader::ReadByteCode(asCScriptFunction *func)
// Read number of instructions
asUINT total, numInstructions;
total = numInstructions = ReadEncodedUInt();
total = numInstructions = SanityCheck(ReadEncodedUInt(), 1000000);
// Reserve some space for the instructions
func->scriptData->byteCode.AllocateNoConstruct(numInstructions, false);
@@ -2664,7 +2689,7 @@ void asCReader::ReadUsedTypeIds()
{
TimeIt("asCReader::ReadUsedTypeIds");
asUINT count = ReadEncodedUInt();
asUINT count = SanityCheck(ReadEncodedUInt(), 1000000);
usedTypeIds.Allocate(count, false);
for( asUINT n = 0; n < count; n++ )
{
@@ -2678,7 +2703,7 @@ void asCReader::ReadUsedGlobalProps()
{
TimeIt("asCReader::ReadUsedGlobalProps");
int c = ReadEncodedUInt();
int c = SanityCheck(ReadEncodedUInt(), 1000000);
usedGlobalProperties.Allocate(c, false);
@@ -2719,7 +2744,7 @@ void asCReader::ReadUsedObjectProps()
{
TimeIt("asCReader::ReadUsedObjectProps");
asUINT c = ReadEncodedUInt();
asUINT c = SanityCheck(ReadEncodedUInt(), 1000000);
usedObjectProperties.SetLength(c);
for( asUINT n = 0; n < c; n++ )

View File

@@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2017 Andreas Jonsson
Copyright (c) 2003-2021 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
@@ -76,7 +76,10 @@ protected:
void ReadByteCode(asCScriptFunction *func);
asWORD ReadEncodedUInt16();
asUINT ReadEncodedUInt();
int ReadEncodedInt();
asQWORD ReadEncodedUInt64();
asUINT SanityCheck(asUINT val, asUINT max);
int SanityCheck(int val, asUINT max);
void ReadUsedTypeIds();
void ReadUsedFunctions();

View File

@@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2020 Andreas Jonsson
Copyright (c) 2003-2021 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
@@ -951,12 +951,16 @@ asCModule *asCScriptEngine::FindNewOwnerForSharedFunc(asCScriptFunction *in_func
if( in_func->module != in_mod)
return in_func->module;
if (in_func->objectType && in_func->objectType->module &&
in_func->objectType->module != in_func->module)
// Check if this is a class method or class factory for a type that has already been moved to a different module
if ((in_func->objectType && in_func->objectType->module && in_func->objectType->module != in_func->module) ||
(in_func->IsFactory() && in_func->returnType.GetTypeInfo()->module && in_func->returnType.GetTypeInfo()->module != in_func->module))
{
// The object type for the method has already been transferred to
// another module, so transfer the method to the same module
in_func->module = in_func->objectType->module;
if (in_func->objectType)
in_func->module = in_func->objectType->module;
else
in_func->module = in_func->returnType.GetTypeInfo()->module;
// Make sure the function is listed in the module
// The compiler may not have done this earlier, since the object
@@ -1370,7 +1374,9 @@ int asCScriptEngine::GetFactoryIdByDecl(const asCObjectType *ot, const char *dec
for( asUINT n = 0; n < ot->beh.factories.GetLength(); n++ )
{
asCScriptFunction *f = scriptFunctions[ot->beh.factories[n]];
if( f->IsSignatureEqual(&func) )
// We don't really care if the name of the function is correct
if( f->IsSignatureExceptNameEqual(&func) )
{
id = ot->beh.factories[n];
break;
@@ -2156,7 +2162,9 @@ int asCScriptEngine::RegisterBehaviourToObjectType(asCObjectType *objectType, as
}
// Verify the parameters
if( func.parameterTypes.GetLength() != 1 || !func.parameterTypes[0].IsReference() )
// The templates take a hidden parameter with the object type
if( (!(objectType->flags & asOBJ_TEMPLATE) && (func.parameterTypes.GetLength() != 1 || !func.parameterTypes[0].IsReference())) ||
((objectType->flags & asOBJ_TEMPLATE) && (func.parameterTypes.GetLength() != 2 || !func.parameterTypes[0].IsReference() || !func.parameterTypes[1].IsReference())) )
{
if( listPattern )
listPattern->Destroy(this);
@@ -4960,7 +4968,8 @@ int asCScriptEngine::RefCastObject(void *obj, asITypeInfo *fromType, asITypeInfo
// Look for ref cast behaviours
asCScriptFunction *universalCastFunc = 0;
asCObjectType *from = reinterpret_cast<asCObjectType*>(fromType);
asCObjectType *from = CastToObjectType(reinterpret_cast< asCTypeInfo*>(fromType));
if( from == 0 ) return asINVALID_ARG;
for( asUINT n = 0; n < from->methods.GetLength(); n++ )
{
asCScriptFunction *func = scriptFunctions[from->methods[n]];
@@ -5044,7 +5053,8 @@ void *asCScriptEngine::CreateScriptObject(const asITypeInfo *type)
{
if( type == 0 ) return 0;
asCObjectType *objType = const_cast<asCObjectType*>(reinterpret_cast<const asCObjectType *>(type));
asCObjectType *objType = CastToObjectType(const_cast<asCTypeInfo*>(reinterpret_cast<const asCTypeInfo*>(type)));
if (objType == 0) return 0;
void *ptr = 0;
// Check that there is a default factory for ref types
@@ -5243,7 +5253,9 @@ void *asCScriptEngine::CreateUninitializedScriptObject(const asITypeInfo *type)
if( type == 0 || !(type->GetFlags() & asOBJ_SCRIPT_OBJECT) )
return 0;
asCObjectType *objType = const_cast<asCObjectType*>(reinterpret_cast<const asCObjectType*>(type));
asCObjectType *objType = CastToObjectType(const_cast<asCTypeInfo*>(reinterpret_cast<const asCTypeInfo*>(type)));
if (objType == 0)
return 0;
// Construct the object, but do not call the actual constructor that initializes the members
// The initialization will be done by the application afterwards, e.g. through serialization.
@@ -5260,9 +5272,11 @@ void *asCScriptEngine::CreateScriptObjectCopy(void *origObj, const asITypeInfo *
{
if( origObj == 0 || type == 0 ) return 0;
const asCObjectType* ot = CastToObjectType(const_cast<asCTypeInfo*>(reinterpret_cast<const asCTypeInfo*>(type)));
if (ot == 0) return 0;
void *newObj = 0;
const asCObjectType *ot = reinterpret_cast<const asCObjectType*>(type);
if ((ot->flags & asOBJ_SCRIPT_OBJECT) && ot->beh.copyfactory)
{
// Call the script class' default factory with a context
@@ -5286,7 +5300,7 @@ void *asCScriptEngine::CreateScriptObjectCopy(void *origObj, const asITypeInfo *
}
#endif
}
else if( ot->beh.copyconstruct )
else if(ot->beh.copyconstruct )
{
// Manually allocate the memory, then call the copy constructor
newObj = CallAlloc(ot);
@@ -5351,7 +5365,8 @@ int asCScriptEngine::AssignScriptObject(void *dstObj, void *srcObj, const asITyp
// TODO: Warn about invalid call in message stream (make it optional)
if( type == 0 || dstObj == 0 || srcObj == 0 ) return asINVALID_ARG;
const asCObjectType *objType = reinterpret_cast<const asCObjectType*>(type);
const asCObjectType *objType = CastToObjectType(const_cast<asCTypeInfo*>(reinterpret_cast<const asCTypeInfo*>(type)));
if (objType == 0) return asINVALID_ARG;
// If value assign for ref types has been disabled, then don't do anything if the type is a ref type
if (ep.disallowValueAssignForRefType && (objType->flags & asOBJ_REF) && !(objType->flags & asOBJ_SCOPED))
@@ -5389,7 +5404,7 @@ void asCScriptEngine::AddRefScriptObject(void *obj, const asITypeInfo *type)
// Make sure it is not a null pointer
if( obj == 0 || type == 0 ) return;
const asCTypeInfo *ti = static_cast<const asCTypeInfo*>(type);
const asCTypeInfo *ti = reinterpret_cast<const asCTypeInfo*>(type);
if (ti->flags & asOBJ_FUNCDEF)
{
CallObjectMethod(obj, functionBehaviours.beh.addref);
@@ -5411,7 +5426,7 @@ void asCScriptEngine::ReleaseScriptObject(void *obj, const asITypeInfo *type)
// Make sure it is not a null pointer
if( obj == 0 || type == 0 ) return;
const asCTypeInfo *ti = static_cast<const asCTypeInfo*>(type);
const asCTypeInfo *ti = reinterpret_cast<const asCTypeInfo*>(type);
if (ti->flags & asOBJ_FUNCDEF)
{
CallObjectMethod(obj, functionBehaviours.beh.release);

View File

@@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2020 Andreas Jonsson
Copyright (c) 2003-2021 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
@@ -306,7 +306,9 @@ int asCScriptFunction::ParseListPattern(asSListPatternNode *&target, const char
asCBuilder builder(engine, 0);
asCScriptCode code;
code.SetCode("", decl, 0, false);
dt = builder.CreateDataTypeFromNode(listNodes, &code, engine->defaultNamespace, false, CastToObjectType(returnType.GetTypeInfo()));
// For list factory we get the object type from the return type, for list constructor we get it from the object type directly
dt = builder.CreateDataTypeFromNode(listNodes, &code, engine->defaultNamespace, false, objectType ? objectType : CastToObjectType(returnType.GetTypeInfo()));
node->next = asNEW(asSListPatternDataTypeNode)(dt);
node = node->next;
@@ -1722,5 +1724,20 @@ bool asCScriptFunction::IsProperty() const
return traits.GetTrait(asTRAIT_PROPERTY);
}
// internal
bool asCScriptFunction::IsFactory() const
{
if (objectType) return false;
asCObjectType* type = CastToObjectType(returnType.GetTypeInfo());
if (type == 0) return false;
if (type->name != name) return false;
if (type->nameSpace != nameSpace) return false;
return true;
}
END_AS_NAMESPACE

View File

@@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2019 Andreas Jonsson
Copyright (c) 2003-2021 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
@@ -215,6 +215,7 @@ public:
void SetProtected(bool set) { traits.SetTrait(asTRAIT_PROTECTED, set); }
void SetPrivate(bool set) { traits.SetTrait(asTRAIT_PRIVATE, set); }
void SetProperty(bool set) { traits.SetTrait(asTRAIT_PROPERTY, set); }
bool IsFactory() const;
asCScriptFunction(asCScriptEngine *engine, asCModule *mod, asEFuncType funcType);
~asCScriptFunction();

View File

@@ -336,6 +336,7 @@ asCScriptObject::asCScriptObject(asCObjectType *ot, bool doInitialize)
{
refCount.set(1);
objType = ot;
objType->AddRef();
isDestructCalled = false;
extra = 0;
hasRefCountReachedZero = false;
@@ -480,6 +481,7 @@ asCScriptObject::~asCScriptObject()
}
}
objType->Release();
objType = 0;
// Something is really wrong if the refCount is not 0 by now

View File

@@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2012-2015 Andreas Jonsson
Copyright (c) 2012-2021 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any

View File

@@ -1,6 +1,6 @@
/*
AngelCode Scripting Library
Copyright (c) 2003-2019 Andreas Jonsson
Copyright (c) 2003-2021 Andreas Jonsson
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
@@ -48,7 +48,7 @@
#define TXT_ATTR_s_INFORMED_MULTIPLE_TIMES "Attribute '%s' informed multiple times"
#define TXT_AUTO_NOT_ALLOWED "Auto is not allowed here"
#define TXT_BOTH_MUST_BE_SAME "Both expressions must have the same type"
#define TXT_BOTH_MUST_BE_SAME "Can't find unambiguous implicit conversion to make both expressions have the same type"
#define TXT_BOTH_CONDITIONS_MUST_CALL_CONSTRUCTOR "Both conditions must call constructor"
#define TEXT_BASE_DOESNT_HAVE_DEF_CONSTR "Base class doesn't have default constructor. Make explicit call to base constructor"
@@ -189,6 +189,7 @@
#define TXT_NAME_CONFLICT_s_IS_MIXIN "Name conflict. '%s' is a mixin class."
#define TXT_NAME_CONFLICT_s_IS_VIRTPROP "Name conflict. '%s' is a virtual property."
#define TXT_NAME_CONFLICT_s_STRUCT "Name conflict. '%s' is a class."
#define TXT_NAME_CONFLICT_s_INTF "Name conflict. '%s' is an interface."
#define TXT_NAME_CONFLICT_s_OBJ_PROPERTY "Name conflict. '%s' is an object property."
#define TXT_NAME_CONFLICT_s_METHOD "Name conflict. '%s' is a class method."
#define TXT_NAME_CONFLICT_s_ALREADY_USED "Name conflict. '%s' is already used."