|
|
@@ -1,6 +1,6 @@
|
|
|
/*
|
|
|
AngelCode Scripting Library
|
|
|
- Copyright (c) 2003-2012 Andreas Jonsson
|
|
|
+ Copyright (c) 2003-2013 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
|
|
|
@@ -127,7 +127,32 @@ int asCReader::ReadInner()
|
|
|
return asOUT_OF_MEMORY;
|
|
|
|
|
|
ReadObjectTypeDeclaration(ot, 1);
|
|
|
- engine->classTypes.PushLast(ot);
|
|
|
+
|
|
|
+ // If the type is shared then we should use the original if it exists
|
|
|
+ bool sharedExists = false;
|
|
|
+ if( ot->IsShared() )
|
|
|
+ {
|
|
|
+ for( asUINT n = 0; n < engine->classTypes.GetLength(); n++ )
|
|
|
+ {
|
|
|
+ asCObjectType *t = engine->classTypes[n];
|
|
|
+ if( t &&
|
|
|
+ t->IsShared() &&
|
|
|
+ t->name == ot->name &&
|
|
|
+ t->nameSpace == ot->nameSpace &&
|
|
|
+ (t->flags & asOBJ_ENUM) )
|
|
|
+ {
|
|
|
+ asDELETE(ot, asCObjectType);
|
|
|
+ ot = t;
|
|
|
+ sharedExists = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if( sharedExists )
|
|
|
+ existingShared.Insert(ot, true);
|
|
|
+ else
|
|
|
+ engine->classTypes.PushLast(ot);
|
|
|
module->enumTypes.PushLast(ot);
|
|
|
ot->AddRef();
|
|
|
ReadObjectTypeDeclaration(ot, 2);
|
|
|
@@ -157,6 +182,7 @@ int asCReader::ReadInner()
|
|
|
if( t &&
|
|
|
t->IsShared() &&
|
|
|
t->name == ot->name &&
|
|
|
+ t->nameSpace == ot->nameSpace &&
|
|
|
t->IsInterface() == ot->IsInterface() )
|
|
|
{
|
|
|
asDELETE(ot, asCObjectType);
|
|
|
@@ -173,9 +199,8 @@ int asCReader::ReadInner()
|
|
|
{
|
|
|
engine->classTypes.PushLast(ot);
|
|
|
|
|
|
- // Add script classes to the GC
|
|
|
- if( (ot->GetFlags() & asOBJ_SCRIPT_OBJECT) && !ot->IsInterface() )
|
|
|
- engine->gc.AddScriptObjectToGC(ot, &engine->objectTypeBehaviours);
|
|
|
+ // Set this module as the owner
|
|
|
+ ot->module = module;
|
|
|
}
|
|
|
module->classTypes.PushLast(ot);
|
|
|
ot->AddRef();
|
|
|
@@ -188,7 +213,8 @@ int asCReader::ReadInner()
|
|
|
module->funcDefs.Allocate(count, 0);
|
|
|
for( i = 0; i < count && !error; i++ )
|
|
|
{
|
|
|
- asCScriptFunction *func = ReadFunction(false, true);
|
|
|
+ bool isNew;
|
|
|
+ asCScriptFunction *func = ReadFunction(isNew, false, true);
|
|
|
if( func )
|
|
|
module->funcDefs.PushLast(func);
|
|
|
else
|
|
|
@@ -238,7 +264,7 @@ int asCReader::ReadInner()
|
|
|
|
|
|
// scriptGlobals[]
|
|
|
count = ReadEncodedUInt();
|
|
|
- if( engine->ep.disallowGlobalVars )
|
|
|
+ if( count && engine->ep.disallowGlobalVars )
|
|
|
{
|
|
|
engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, TXT_GLOBAL_VARS_NOT_ALLOWED);
|
|
|
error = true;
|
|
|
@@ -254,7 +280,8 @@ int asCReader::ReadInner()
|
|
|
for( i = 0; i < count && !error; ++i )
|
|
|
{
|
|
|
size_t len = module->scriptFunctions.GetLength();
|
|
|
- func = ReadFunction();
|
|
|
+ bool isNew;
|
|
|
+ func = ReadFunction(isNew);
|
|
|
if( func == 0 )
|
|
|
{
|
|
|
error = true;
|
|
|
@@ -287,6 +314,7 @@ int asCReader::ReadInner()
|
|
|
func->id = 0;
|
|
|
func->byteCode.SetLength(0);
|
|
|
func->Release();
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -296,7 +324,8 @@ int asCReader::ReadInner()
|
|
|
count = ReadEncodedUInt();
|
|
|
for( i = 0; i < count && !error; ++i )
|
|
|
{
|
|
|
- func = ReadFunction(false, false);
|
|
|
+ bool isNew;
|
|
|
+ func = ReadFunction(isNew, false, false);
|
|
|
if( func )
|
|
|
{
|
|
|
module->globalFunctions.Put(func);
|
|
|
@@ -317,7 +346,8 @@ int asCReader::ReadInner()
|
|
|
if( info == 0 )
|
|
|
return asOUT_OF_MEMORY;
|
|
|
|
|
|
- info->importedFunctionSignature = ReadFunction(false, false);
|
|
|
+ bool isNew;
|
|
|
+ info->importedFunctionSignature = ReadFunction(isNew, false, false);
|
|
|
if( info->importedFunctionSignature == 0 )
|
|
|
{
|
|
|
error = true;
|
|
|
@@ -372,18 +402,26 @@ int asCReader::ReadInner()
|
|
|
ReadUsedObjectProps();
|
|
|
|
|
|
// Validate the template types
|
|
|
- for( i = 0; i < usedTypes.GetLength() && !error; i++ )
|
|
|
+ if( !error )
|
|
|
{
|
|
|
- if( (usedTypes[i]->flags & asOBJ_TEMPLATE) &&
|
|
|
- usedTypes[i]->templateSubType.IsValid() &&
|
|
|
- usedTypes[i]->beh.templateCallback )
|
|
|
+ for( i = 0; i < usedTypes.GetLength() && !error; i++ )
|
|
|
{
|
|
|
+ if( !(usedTypes[i]->flags & asOBJ_TEMPLATE) ||
|
|
|
+ !usedTypes[i]->beh.templateCallback )
|
|
|
+ continue;
|
|
|
+
|
|
|
bool dontGarbageCollect = false;
|
|
|
asCScriptFunction *callback = engine->scriptFunctions[usedTypes[i]->beh.templateCallback];
|
|
|
if( !engine->CallGlobalFunctionRetBool(usedTypes[i], &dontGarbageCollect, callback->sysFuncIntf, callback) )
|
|
|
{
|
|
|
+ asCString sub = usedTypes[i]->templateSubTypes[0].Format();
|
|
|
+ for( asUINT n = 1; n < usedTypes[i]->templateSubTypes.GetLength(); n++ )
|
|
|
+ {
|
|
|
+ sub += ",";
|
|
|
+ sub += usedTypes[i]->templateSubTypes[n].Format();
|
|
|
+ }
|
|
|
asCString str;
|
|
|
- str.Format(TXT_INSTANCING_INVLD_TMPL_TYPE_s_s, usedTypes[i]->name.AddressOf(), usedTypes[i]->templateSubType.Format().AddressOf());
|
|
|
+ str.Format(TXT_INSTANCING_INVLD_TMPL_TYPE_s_s, usedTypes[i]->name.AddressOf(), sub.AddressOf());
|
|
|
engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
|
|
|
error = true;
|
|
|
}
|
|
|
@@ -568,8 +606,9 @@ void asCReader::ReadFunctionSignature(asCScriptFunction *func)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-asCScriptFunction *asCReader::ReadFunction(bool addToModule, bool addToEngine, bool addToGC)
|
|
|
+asCScriptFunction *asCReader::ReadFunction(bool &isNew, bool addToModule, bool addToEngine, bool addToGC)
|
|
|
{
|
|
|
+ isNew = false;
|
|
|
if( error ) return 0;
|
|
|
|
|
|
char c;
|
|
|
@@ -595,6 +634,7 @@ asCScriptFunction *asCReader::ReadFunction(bool addToModule, bool addToEngine, b
|
|
|
}
|
|
|
|
|
|
// Load the new function
|
|
|
+ isNew = true;
|
|
|
asCScriptFunction *func = asNEW(asCScriptFunction)(engine,module,asFUNC_DUMMY);
|
|
|
if( func == 0 )
|
|
|
{
|
|
|
@@ -610,11 +650,9 @@ asCScriptFunction *asCReader::ReadFunction(bool addToModule, bool addToEngine, b
|
|
|
|
|
|
ReadFunctionSignature(func);
|
|
|
|
|
|
- func->id = engine->GetNextScriptFunctionId();
|
|
|
-
|
|
|
if( func->funcType == asFUNC_SCRIPT )
|
|
|
{
|
|
|
- if( addToGC )
|
|
|
+ if( addToGC && !addToModule )
|
|
|
engine->gc.AddScriptObjectToGC(func, &engine->functionBehaviours);
|
|
|
|
|
|
ReadByteCode(func);
|
|
|
@@ -653,6 +691,12 @@ asCScriptFunction *asCReader::ReadFunction(bool addToModule, bool addToEngine, b
|
|
|
func->lineNumbers.SetLength(length);
|
|
|
for( i = 0; i < length; ++i )
|
|
|
func->lineNumbers[i] = ReadEncodedUInt();
|
|
|
+
|
|
|
+ // Read the array of script sections
|
|
|
+ length = ReadEncodedUInt();
|
|
|
+ func->sectionIdxs.SetLength(length);
|
|
|
+ for( i = 0; i < length; ++i )
|
|
|
+ func->sectionIdxs[i] = ReadEncodedUInt();
|
|
|
}
|
|
|
|
|
|
ReadData(&func->isShared, 1);
|
|
|
@@ -679,6 +723,8 @@ asCScriptFunction *asCReader::ReadFunction(bool addToModule, bool addToEngine, b
|
|
|
ReadDataType(&var->type);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ ReadData(&func->dontCleanUpOnException, 1);
|
|
|
}
|
|
|
else if( func->funcType == asFUNC_VIRTUAL )
|
|
|
{
|
|
|
@@ -699,7 +745,10 @@ asCScriptFunction *asCReader::ReadFunction(bool addToModule, bool addToEngine, b
|
|
|
module->scriptFunctions.PushLast(func);
|
|
|
}
|
|
|
if( addToEngine )
|
|
|
+ {
|
|
|
+ func->id = engine->GetNextScriptFunctionId();
|
|
|
engine->SetScriptFunction(func);
|
|
|
+ }
|
|
|
if( func->objectType )
|
|
|
func->ComputeSignatureId();
|
|
|
|
|
|
@@ -744,25 +793,57 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
|
|
|
if( ot->flags & asOBJ_ENUM )
|
|
|
{
|
|
|
int count = ReadEncodedUInt();
|
|
|
- ot->enumValues.Allocate(count, 0);
|
|
|
- for( int n = 0; n < count; n++ )
|
|
|
+ bool sharedExists = existingShared.MoveTo(0, ot);
|
|
|
+ if( !sharedExists )
|
|
|
{
|
|
|
- asSEnumValue *e = asNEW(asSEnumValue);
|
|
|
- if( e == 0 )
|
|
|
+ ot->enumValues.Allocate(count, 0);
|
|
|
+ for( int n = 0; n < count; n++ )
|
|
|
{
|
|
|
- // Out of memory
|
|
|
- error = true;
|
|
|
- return;
|
|
|
+ asSEnumValue *e = asNEW(asSEnumValue);
|
|
|
+ if( e == 0 )
|
|
|
+ {
|
|
|
+ // Out of memory
|
|
|
+ error = true;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ ReadString(&e->name);
|
|
|
+ ReadData(&e->value, 4); // TODO: Should be encoded
|
|
|
+ ot->enumValues.PushLast(e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // Verify that the enum values exists in the original
|
|
|
+ asCString name;
|
|
|
+ int value;
|
|
|
+ for( int n = 0; n < count; n++ )
|
|
|
+ {
|
|
|
+ ReadString(&name);
|
|
|
+ ReadData(&value, 4); // TODO: Should be encoded
|
|
|
+ bool found = false;
|
|
|
+ for( asUINT e = 0; e < ot->enumValues.GetLength(); e++ )
|
|
|
+ {
|
|
|
+ if( ot->enumValues[e]->name == name &&
|
|
|
+ ot->enumValues[e]->value == value )
|
|
|
+ {
|
|
|
+ found = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if( !found )
|
|
|
+ {
|
|
|
+ asCString str;
|
|
|
+ str.Format(TXT_SHARED_s_DOESNT_MATCH_ORIGINAL, ot->GetName());
|
|
|
+ engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
|
|
|
+ error = true;
|
|
|
+ }
|
|
|
}
|
|
|
- ReadString(&e->name);
|
|
|
- ReadData(&e->value, 4);
|
|
|
- ot->enumValues.PushLast(e);
|
|
|
}
|
|
|
}
|
|
|
else if( ot->flags & asOBJ_TYPEDEF )
|
|
|
{
|
|
|
eTokenType t = (eTokenType)ReadEncodedUInt();
|
|
|
- ot->templateSubType = asCDataType::CreatePrimitive(t, false);
|
|
|
+ ot->templateSubTypes.PushLast(asCDataType::CreatePrimitive(t, false));
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
@@ -774,7 +855,9 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
|
|
|
asCObjectType *dt = ReadObjectType();
|
|
|
if( ot->derivedFrom != dt )
|
|
|
{
|
|
|
- // TODO: Write message
|
|
|
+ asCString str;
|
|
|
+ str.Format(TXT_SHARED_s_DOESNT_MATCH_ORIGINAL, ot->GetName());
|
|
|
+ engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
|
|
|
error = true;
|
|
|
}
|
|
|
}
|
|
|
@@ -794,7 +877,9 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
|
|
|
asCObjectType *intf = ReadObjectType();
|
|
|
if( !ot->Implements(intf) )
|
|
|
{
|
|
|
- // TODO: Write message
|
|
|
+ asCString str;
|
|
|
+ str.Format(TXT_SHARED_s_DOESNT_MATCH_ORIGINAL, ot->GetName());
|
|
|
+ engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
|
|
|
error = true;
|
|
|
}
|
|
|
}
|
|
|
@@ -812,7 +897,8 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
|
|
|
// behaviours
|
|
|
if( !ot->IsInterface() && ot->flags != asOBJ_TYPEDEF && ot->flags != asOBJ_ENUM )
|
|
|
{
|
|
|
- asCScriptFunction *func = ReadFunction(!sharedExists, !sharedExists, !sharedExists);
|
|
|
+ bool isNew;
|
|
|
+ asCScriptFunction *func = ReadFunction(isNew, !sharedExists, !sharedExists, !sharedExists);
|
|
|
if( sharedExists )
|
|
|
{
|
|
|
// Find the real function in the object, and update the savedFunctions array
|
|
|
@@ -825,15 +911,20 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- // TODO: Write message
|
|
|
+ asCString str;
|
|
|
+ str.Format(TXT_SHARED_s_DOESNT_MATCH_ORIGINAL, ot->GetName());
|
|
|
+ engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
|
|
|
error = true;
|
|
|
}
|
|
|
- // Destroy the function without releasing any references
|
|
|
if( func )
|
|
|
{
|
|
|
- func->id = 0;
|
|
|
- func->byteCode.SetLength(0);
|
|
|
- func->Release();
|
|
|
+ if( isNew )
|
|
|
+ {
|
|
|
+ // Destroy the function without releasing any references
|
|
|
+ func->id = 0;
|
|
|
+ func->byteCode.SetLength(0);
|
|
|
+ func->Release();
|
|
|
+ }
|
|
|
module->scriptFunctions.PushLast(realFunc);
|
|
|
realFunc->AddRef();
|
|
|
dontTranslate.Insert(realFunc, true);
|
|
|
@@ -853,7 +944,8 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
|
|
|
size = ReadEncodedUInt();
|
|
|
for( int n = 0; n < size; n++ )
|
|
|
{
|
|
|
- asCScriptFunction *func = ReadFunction(!sharedExists, !sharedExists, !sharedExists);
|
|
|
+ bool isNew;
|
|
|
+ asCScriptFunction *func = ReadFunction(isNew, !sharedExists, !sharedExists, !sharedExists);
|
|
|
if( func )
|
|
|
{
|
|
|
if( sharedExists )
|
|
|
@@ -877,13 +969,18 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
|
|
|
}
|
|
|
if( !found )
|
|
|
{
|
|
|
- // TODO: Write message
|
|
|
+ asCString str;
|
|
|
+ str.Format(TXT_SHARED_s_DOESNT_MATCH_ORIGINAL, ot->GetName());
|
|
|
+ engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
|
|
|
error = true;
|
|
|
}
|
|
|
- // Destroy the function without releasing any references
|
|
|
- func->id = 0;
|
|
|
- func->byteCode.SetLength(0);
|
|
|
- func->Release();
|
|
|
+ if( isNew )
|
|
|
+ {
|
|
|
+ // Destroy the function without releasing any references
|
|
|
+ func->id = 0;
|
|
|
+ func->byteCode.SetLength(0);
|
|
|
+ func->Release();
|
|
|
+ }
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
@@ -900,7 +997,7 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
|
|
|
error = true;
|
|
|
}
|
|
|
|
|
|
- func = ReadFunction(!sharedExists, !sharedExists, !sharedExists);
|
|
|
+ func = ReadFunction(isNew, !sharedExists, !sharedExists, !sharedExists);
|
|
|
if( func )
|
|
|
{
|
|
|
if( sharedExists )
|
|
|
@@ -924,13 +1021,18 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
|
|
|
}
|
|
|
if( !found )
|
|
|
{
|
|
|
- // TODO: Write message
|
|
|
+ asCString str;
|
|
|
+ str.Format(TXT_SHARED_s_DOESNT_MATCH_ORIGINAL, ot->GetName());
|
|
|
+ engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
|
|
|
error = true;
|
|
|
}
|
|
|
- // Destroy the function without releasing any references
|
|
|
- func->id = 0;
|
|
|
- func->byteCode.SetLength(0);
|
|
|
- func->Release();
|
|
|
+ if( isNew )
|
|
|
+ {
|
|
|
+ // Destroy the function without releasing any references
|
|
|
+ func->id = 0;
|
|
|
+ func->byteCode.SetLength(0);
|
|
|
+ func->Release();
|
|
|
+ }
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
@@ -954,7 +1056,8 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
|
|
|
int n;
|
|
|
for( n = 0; n < size; n++ )
|
|
|
{
|
|
|
- asCScriptFunction *func = ReadFunction(!sharedExists, !sharedExists, !sharedExists);
|
|
|
+ bool isNew;
|
|
|
+ asCScriptFunction *func = ReadFunction(isNew, !sharedExists, !sharedExists, !sharedExists);
|
|
|
if( func )
|
|
|
{
|
|
|
if( sharedExists )
|
|
|
@@ -978,12 +1081,12 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
|
|
|
}
|
|
|
if( !found )
|
|
|
{
|
|
|
- // TODO: Write message
|
|
|
+ asCString str;
|
|
|
+ str.Format(TXT_SHARED_s_DOESNT_MATCH_ORIGINAL, ot->GetName());
|
|
|
+ engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
|
|
|
error = true;
|
|
|
}
|
|
|
- // If the function received wasn't an already existing
|
|
|
- // function we must now destroy it
|
|
|
- if( !savedFunctions.Exists(func) )
|
|
|
+ if( isNew )
|
|
|
{
|
|
|
// Destroy the function without releasing any references
|
|
|
func->id = 0;
|
|
|
@@ -993,6 +1096,16 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
+ // If the method is the assignment operator we need to replace the default implementation
|
|
|
+ if( func->name == "opAssign" && func->parameterTypes.GetLength() == 1 &&
|
|
|
+ func->parameterTypes[0].GetObjectType() == func->objectType &&
|
|
|
+ (func->inOutFlags[0] & asTM_INREF) )
|
|
|
+ {
|
|
|
+ engine->scriptFunctions[ot->beh.copy]->Release();
|
|
|
+ ot->beh.copy = func->id;
|
|
|
+ func->AddRef();
|
|
|
+ }
|
|
|
+
|
|
|
ot->methods.PushLast(func->id);
|
|
|
func->AddRef();
|
|
|
}
|
|
|
@@ -1008,7 +1121,8 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
|
|
|
size = ReadEncodedUInt();
|
|
|
for( n = 0; n < size; n++ )
|
|
|
{
|
|
|
- asCScriptFunction *func = ReadFunction(!sharedExists, !sharedExists, !sharedExists);
|
|
|
+ bool isNew;
|
|
|
+ asCScriptFunction *func = ReadFunction(isNew, !sharedExists, !sharedExists, !sharedExists);
|
|
|
if( func )
|
|
|
{
|
|
|
if( sharedExists )
|
|
|
@@ -1032,12 +1146,12 @@ void asCReader::ReadObjectTypeDeclaration(asCObjectType *ot, int phase)
|
|
|
}
|
|
|
if( !found )
|
|
|
{
|
|
|
- // TODO: Write message
|
|
|
+ asCString str;
|
|
|
+ str.Format(TXT_SHARED_s_DOESNT_MATCH_ORIGINAL, ot->GetName());
|
|
|
+ engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
|
|
|
error = true;
|
|
|
}
|
|
|
- // If the function received wasn't an already existing
|
|
|
- // function we must now destroy it
|
|
|
- if( !savedFunctions.Exists(func) )
|
|
|
+ if( isNew )
|
|
|
{
|
|
|
// Destroy the function without releasing any references
|
|
|
func->id = 0;
|
|
|
@@ -1212,7 +1326,10 @@ void asCReader::ReadGlobalProperty()
|
|
|
ReadData(&f, 1);
|
|
|
if( f )
|
|
|
{
|
|
|
- asCScriptFunction *func = ReadFunction(false, true);
|
|
|
+ bool isNew;
|
|
|
+ // Do not add the function to the GC at this time. It will
|
|
|
+ // only be added to the GC when the module releases the property
|
|
|
+ asCScriptFunction *func = ReadFunction(isNew, false, true, false);
|
|
|
if( func )
|
|
|
{
|
|
|
prop->SetInitFunc(func);
|
|
|
@@ -1313,7 +1430,10 @@ void asCReader::ReadDataType(asCDataType *dt)
|
|
|
if( isObjectHandle )
|
|
|
{
|
|
|
dt->MakeReadOnly(isHandleToConst);
|
|
|
- dt->MakeHandle(true);
|
|
|
+
|
|
|
+ // Here we must allow a scoped type to be a handle
|
|
|
+ // e.g. if the datatype is for a system function
|
|
|
+ dt->MakeHandle(true, true);
|
|
|
}
|
|
|
dt->MakeReadOnly(isReadOnly);
|
|
|
dt->MakeReference(isReference);
|
|
|
@@ -1342,41 +1462,48 @@ asCObjectType* asCReader::ReadObjectType()
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
- ReadData(&ch, 1);
|
|
|
- if( ch == 's' )
|
|
|
+ asUINT numSubTypes = ReadEncodedUInt();
|
|
|
+ asCArray<asCDataType> subTypes;
|
|
|
+ for( asUINT n = 0; n < numSubTypes; n++ )
|
|
|
{
|
|
|
- asCDataType dt;
|
|
|
- ReadDataType(&dt);
|
|
|
-
|
|
|
- if( tmpl->templateSubType.GetObjectType() == dt.GetObjectType() )
|
|
|
- ot = tmpl;
|
|
|
+ ReadData(&ch, 1);
|
|
|
+ if( ch == 's' )
|
|
|
+ {
|
|
|
+ asCDataType dt;
|
|
|
+ ReadDataType(&dt);
|
|
|
+ subTypes.PushLast(dt);
|
|
|
+ }
|
|
|
else
|
|
|
- ot = engine->GetTemplateInstanceType(tmpl, dt);
|
|
|
-
|
|
|
- if( ot == 0 )
|
|
|
{
|
|
|
- asCString str;
|
|
|
- str.Format(TXT_INSTANCING_INVLD_TMPL_TYPE_s_s, typeName.AddressOf(), dt.Format().AddressOf());
|
|
|
- engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
|
|
|
- error = true;
|
|
|
- return 0;
|
|
|
+ eTokenType tokenType = (eTokenType)ReadEncodedUInt();
|
|
|
+ asCDataType dt = asCDataType::CreatePrimitive(tokenType, false);
|
|
|
+ subTypes.PushLast(dt);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ // Return the actual template if the subtypes are the template's dummy types
|
|
|
+ if( tmpl->templateSubTypes == subTypes )
|
|
|
+ ot = tmpl;
|
|
|
else
|
|
|
{
|
|
|
- eTokenType tokenType = (eTokenType)ReadEncodedUInt();
|
|
|
- asCDataType dt = asCDataType::CreatePrimitive(tokenType, false);
|
|
|
+ // Get the template instance type based on the loaded subtypes
|
|
|
+ ot = engine->GetTemplateInstanceType(tmpl, subTypes);
|
|
|
+ }
|
|
|
|
|
|
- ot = engine->GetTemplateInstanceType(tmpl, dt);
|
|
|
-
|
|
|
- if( ot == 0 )
|
|
|
+ if( ot == 0 )
|
|
|
+ {
|
|
|
+ // Show all subtypes in error message
|
|
|
+ asCString sub = subTypes[0].Format();
|
|
|
+ for( asUINT n = 1; n < subTypes.GetLength(); n++ )
|
|
|
{
|
|
|
- asCString str;
|
|
|
- str.Format(TXT_INSTANCING_INVLD_TMPL_TYPE_s_s, typeName.AddressOf(), dt.Format().AddressOf());
|
|
|
- engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
|
|
|
- error = true;
|
|
|
- return 0;
|
|
|
+ sub += ",";
|
|
|
+ sub += subTypes[n].Format();
|
|
|
}
|
|
|
+ asCString str;
|
|
|
+ str.Format(TXT_INSTANCING_INVLD_TMPL_TYPE_s_s, typeName.AddressOf(), sub.AddressOf());
|
|
|
+ engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
|
|
|
+ error = true;
|
|
|
+ return 0;
|
|
|
}
|
|
|
}
|
|
|
else if( ch == 's' )
|
|
|
@@ -1468,7 +1595,7 @@ void asCReader::ReadByteCode(asCScriptFunction *func)
|
|
|
|
|
|
// Allocate the space for the instruction
|
|
|
asUINT len = asBCTypeSize[asBCInfo[b].type];
|
|
|
- asUINT newSize = func->byteCode.GetLength() + len;
|
|
|
+ asUINT newSize = asUINT(func->byteCode.GetLength()) + len;
|
|
|
if( func->byteCode.GetCapacity() < newSize )
|
|
|
{
|
|
|
// Determine the average size of the loaded instructions and re-estimate the final size
|
|
|
@@ -1864,16 +1991,25 @@ void asCReader::TranslateFunction(asCScriptFunction *func)
|
|
|
int *tid = (int*)&bc[n+1];
|
|
|
*tid = FindTypeId(*tid);
|
|
|
|
|
|
- // COPY is used to copy POD types that don't have the opAssign method
|
|
|
+ // COPY is used to copy POD types that don't have the opAssign method. It is
|
|
|
+ // also used to copy references to scoped types during variable initializations.
|
|
|
// Update the number of dwords to copy as it may be different on the target platform
|
|
|
- asCDataType dt = engine->GetDataTypeFromTypeId(*tid);
|
|
|
- if( !dt.IsValid() )
|
|
|
+ if( (*tid) & asTYPEID_OBJHANDLE )
|
|
|
{
|
|
|
- // TODO: Write error to message
|
|
|
- error = true;
|
|
|
+ // It is the actual reference that is being copied, not the object itself
|
|
|
+ asBC_SWORDARG0(&bc[n]) = AS_PTR_SIZE;
|
|
|
}
|
|
|
else
|
|
|
- asBC_SWORDARG0(&bc[n]) = (short)dt.GetSizeInMemoryDWords();
|
|
|
+ {
|
|
|
+ asCDataType dt = engine->GetDataTypeFromTypeId(*tid);
|
|
|
+ if( !dt.IsValid() )
|
|
|
+ {
|
|
|
+ // TODO: Write error to message
|
|
|
+ error = true;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ asBC_SWORDARG0(&bc[n]) = (short)dt.GetSizeInMemoryDWords();
|
|
|
+ }
|
|
|
}
|
|
|
else if( c == asBC_RET )
|
|
|
{
|
|
|
@@ -1911,12 +2047,12 @@ void asCReader::TranslateFunction(asCScriptFunction *func)
|
|
|
asPWORD *arg = (asPWORD*)&bc[n+1];
|
|
|
*(asCObjectType**)arg = FindObjectType(*(int*)arg);
|
|
|
|
|
|
- // If the object type is a script class then the constructor id must be translated
|
|
|
- asCObjectType *ot = *(asCObjectType**)arg;
|
|
|
- if( ot && (ot->flags & asOBJ_SCRIPT_OBJECT) )
|
|
|
+ // The constructor function id must be translated, unless it is zero
|
|
|
+ int *fid = (int*)&bc[n+1+AS_PTR_SIZE];
|
|
|
+ if( *fid != 0 )
|
|
|
{
|
|
|
- int *fid = (int*)&bc[n+1+AS_PTR_SIZE];
|
|
|
- asCScriptFunction *f = FindFunction(*fid);
|
|
|
+ // Subtract 1 from the id, as it was incremented during the writing
|
|
|
+ asCScriptFunction *f = FindFunction(*fid-1);
|
|
|
if( f )
|
|
|
*fid = f->id;
|
|
|
else
|
|
|
@@ -2112,9 +2248,9 @@ void asCReader::TranslateFunction(asCScriptFunction *func)
|
|
|
// The program position (every even number) needs to be adjusted
|
|
|
// for the line numbers to be in number of dwords instead of number of instructions
|
|
|
for( n = 0; n < func->lineNumbers.GetLength(); n += 2 )
|
|
|
- {
|
|
|
func->lineNumbers[n] = instructionNbrToPos[func->lineNumbers[n]];
|
|
|
- }
|
|
|
+ for( n = 0; n < func->sectionIdxs.GetLength(); n += 2 )
|
|
|
+ func->sectionIdxs[n] = instructionNbrToPos[func->sectionIdxs[n]];
|
|
|
|
|
|
CalculateStackNeeded(func);
|
|
|
}
|
|
|
@@ -2400,11 +2536,26 @@ asCScriptFunction *asCReader::GetCalledFunction(asCScriptFunction *func, asDWORD
|
|
|
}
|
|
|
else if( bc == asBC_CallPtr )
|
|
|
{
|
|
|
- // Find the funcdef from the local variable
|
|
|
+ asUINT v;
|
|
|
int var = asBC_SWORDARG0(&func->byteCode[programPos]);
|
|
|
- for( asUINT v = 0; v < func->objVariablePos.GetLength(); v++ )
|
|
|
+
|
|
|
+ // Find the funcdef from the local variable
|
|
|
+ for( v = 0; v < func->objVariablePos.GetLength(); v++ )
|
|
|
if( func->objVariablePos[v] == var )
|
|
|
return func->funcVariableTypes[v];
|
|
|
+
|
|
|
+ // Look in parameters
|
|
|
+ int paramPos = 0;
|
|
|
+ if( func->objectType )
|
|
|
+ paramPos -= AS_PTR_SIZE;
|
|
|
+ if( func->DoesReturnOnStack() )
|
|
|
+ paramPos -= AS_PTR_SIZE;
|
|
|
+ for( v = 0; v < func->parameterTypes.GetLength(); v++ )
|
|
|
+ {
|
|
|
+ if( var == paramPos )
|
|
|
+ return func->parameterTypes[v].GetFuncDef();
|
|
|
+ paramPos -= func->parameterTypes[v].GetSizeOnStackDWords();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
@@ -2828,6 +2979,17 @@ void asCWriter::WriteFunction(asCScriptFunction* func)
|
|
|
else
|
|
|
WriteEncodedInt64(func->lineNumbers[i]);
|
|
|
}
|
|
|
+
|
|
|
+ // Write the array of script sections
|
|
|
+ length = (asUINT)func->sectionIdxs.GetLength();
|
|
|
+ WriteEncodedInt64(length);
|
|
|
+ for( i = 0; i < length; ++i )
|
|
|
+ {
|
|
|
+ if( (i & 1) == 0 )
|
|
|
+ WriteEncodedInt64(bytecodeNbrByPos[func->sectionIdxs[i]]);
|
|
|
+ else
|
|
|
+ WriteEncodedInt64(func->sectionIdxs[i]);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
WriteData(&func->isShared, 1);
|
|
|
@@ -2846,6 +3008,8 @@ void asCWriter::WriteFunction(asCScriptFunction* func)
|
|
|
WriteDataType(&func->variables[i]->type);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ WriteData(&func->dontCleanUpOnException, 1);
|
|
|
}
|
|
|
else if( func->funcType == asFUNC_VIRTUAL )
|
|
|
{
|
|
|
@@ -2907,7 +3071,7 @@ void asCWriter::WriteObjectTypeDeclaration(asCObjectType *ot, int phase)
|
|
|
}
|
|
|
else if( ot->flags & asOBJ_TYPEDEF )
|
|
|
{
|
|
|
- eTokenType t = ot->templateSubType.GetTokenType();
|
|
|
+ eTokenType t = ot->templateSubTypes[0].GetTokenType();
|
|
|
WriteEncodedInt64(t);
|
|
|
}
|
|
|
else
|
|
|
@@ -3147,24 +3311,28 @@ void asCWriter::WriteObjectType(asCObjectType* ot)
|
|
|
if( ot )
|
|
|
{
|
|
|
// Check for template instances/specializations
|
|
|
- if( ot->templateSubType.GetTokenType() != ttUnrecognizedToken )
|
|
|
+ if( ot->templateSubTypes.GetLength() )
|
|
|
{
|
|
|
ch = 'a';
|
|
|
WriteData(&ch, 1);
|
|
|
WriteString(&ot->name);
|
|
|
|
|
|
- if( ot->templateSubType.IsObject() || ot->templateSubType.IsEnumType() )
|
|
|
- {
|
|
|
- ch = 's';
|
|
|
- WriteData(&ch, 1);
|
|
|
- WriteDataType(&ot->templateSubType);
|
|
|
- }
|
|
|
- else
|
|
|
+ WriteEncodedInt64(ot->templateSubTypes.GetLength());
|
|
|
+ for( asUINT n = 0; n < ot->templateSubTypes.GetLength(); n++ )
|
|
|
{
|
|
|
- ch = 't';
|
|
|
- WriteData(&ch, 1);
|
|
|
- eTokenType t = ot->templateSubType.GetTokenType();
|
|
|
- WriteEncodedInt64(t);
|
|
|
+ if( ot->templateSubTypes[0].IsObject() || ot->templateSubTypes[0].IsEnumType() )
|
|
|
+ {
|
|
|
+ ch = 's';
|
|
|
+ WriteData(&ch, 1);
|
|
|
+ WriteDataType(&ot->templateSubTypes[0]);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ ch = 't';
|
|
|
+ WriteData(&ch, 1);
|
|
|
+ eTokenType t = ot->templateSubTypes[0].GetTokenType();
|
|
|
+ WriteEncodedInt64(t);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
else if( ot->flags & asOBJ_TEMPLATE_SUBTYPE )
|
|
|
@@ -3349,14 +3517,35 @@ int asCWriter::AdjustGetOffset(int offset, asCScriptFunction *func, asDWORD prog
|
|
|
}
|
|
|
else if( bc == asBC_CallPtr )
|
|
|
{
|
|
|
- // Find the funcdef from the local variable
|
|
|
int var = asBC_SWORDARG0(&func->byteCode[n]);
|
|
|
- for( asUINT v = 0; v < func->objVariablePos.GetLength(); v++ )
|
|
|
+ asUINT v;
|
|
|
+ // Find the funcdef from the local variable
|
|
|
+ for( v = 0; v < func->objVariablePos.GetLength(); v++ )
|
|
|
+ {
|
|
|
if( func->objVariablePos[v] == var )
|
|
|
{
|
|
|
calledFunc = func->funcVariableTypes[v];
|
|
|
break;
|
|
|
}
|
|
|
+ }
|
|
|
+ if( !calledFunc )
|
|
|
+ {
|
|
|
+ // Look in parameters
|
|
|
+ int paramPos = 0;
|
|
|
+ if( func->objectType )
|
|
|
+ paramPos -= AS_PTR_SIZE;
|
|
|
+ if( func->DoesReturnOnStack() )
|
|
|
+ paramPos -= AS_PTR_SIZE;
|
|
|
+ for( v = 0; v < func->parameterTypes.GetLength(); v++ )
|
|
|
+ {
|
|
|
+ if( var == paramPos )
|
|
|
+ {
|
|
|
+ calledFunc = func->parameterTypes[v].GetFuncDef();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ paramPos -= func->parameterTypes[v].GetSizeOnStackDWords();
|
|
|
+ }
|
|
|
+ }
|
|
|
break;
|
|
|
}
|
|
|
else if( bc == asBC_REFCPY ||
|
|
|
@@ -3440,9 +3629,12 @@ void asCWriter::WriteByteCode(asCScriptFunction *func)
|
|
|
asCObjectType *ot = *(asCObjectType**)(tmp+1);
|
|
|
*(asPWORD*)(tmp+1) = FindObjectTypeIdx(ot);
|
|
|
|
|
|
- // Translate the constructor func id, if it is a script class
|
|
|
- if( ot->flags & asOBJ_SCRIPT_OBJECT )
|
|
|
- *(int*)&tmp[1+AS_PTR_SIZE] = FindFunctionIndex(engine->scriptFunctions[*(int*)&tmp[1+AS_PTR_SIZE]]);
|
|
|
+ // Translate the constructor func id, unless it is 0
|
|
|
+ if( *(int*)&tmp[1+AS_PTR_SIZE] != 0 )
|
|
|
+ {
|
|
|
+ // Increment 1 to the translated function id, as 0 will be reserved for no function
|
|
|
+ *(int*)&tmp[1+AS_PTR_SIZE] = 1+FindFunctionIndex(engine->scriptFunctions[*(int*)&tmp[1+AS_PTR_SIZE]]);
|
|
|
+ }
|
|
|
}
|
|
|
else if( c == asBC_FREE || // wW_PTR_ARG
|
|
|
c == asBC_REFCPY || // PTR_ARG
|