mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-11 23:32:04 +00:00
This commit is contained in:
commit
20a83f95b9
7 changed files with 73 additions and 9 deletions
|
@ -2515,6 +2515,9 @@ void D_DoomMain (void)
|
||||||
// Create replacements for dehacked pickups
|
// Create replacements for dehacked pickups
|
||||||
FinishDehPatch();
|
FinishDehPatch();
|
||||||
|
|
||||||
|
// clean up the compiler symbols which are not needed any longer.
|
||||||
|
RemoveUnusedSymbols();
|
||||||
|
|
||||||
InitActorNumsFromMapinfo();
|
InitActorNumsFromMapinfo();
|
||||||
InitSpawnablesFromMapinfo();
|
InitSpawnablesFromMapinfo();
|
||||||
PClassActor::StaticSetActorNums();
|
PClassActor::StaticSetActorNums();
|
||||||
|
|
|
@ -3898,3 +3898,45 @@ void FNamespaceManager::ReleaseSymbols()
|
||||||
GlobalNamespace = nullptr;
|
GlobalNamespace = nullptr;
|
||||||
AllNamespaces.Clear();
|
AllNamespaces.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// removes all symbols from the symbol tables.
|
||||||
|
// After running the compiler these are not needed anymore.
|
||||||
|
// Only the namespaces themselves are kept because the type table references them.
|
||||||
|
int FNamespaceManager::RemoveSymbols()
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
for (auto ns : AllNamespaces)
|
||||||
|
{
|
||||||
|
count += ns->Symbols.Symbols.CountUsed();
|
||||||
|
ns->Symbols.ReleaseSymbols();
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoveUnusedSymbols()
|
||||||
|
{
|
||||||
|
// Global symbols are not needed anymore after running the compiler.
|
||||||
|
int count = Namespaces.RemoveSymbols();
|
||||||
|
|
||||||
|
// We do not need any non-field and non-function symbols in structs and classes anymore.
|
||||||
|
for (size_t i = 0; i < countof(TypeTable.TypeHash); ++i)
|
||||||
|
{
|
||||||
|
for (PType *ty = TypeTable.TypeHash[i]; ty != NULL; ty = ty->HashNext)
|
||||||
|
{
|
||||||
|
if (ty->IsKindOf(RUNTIME_CLASS(PStruct)))
|
||||||
|
{
|
||||||
|
auto it = ty->Symbols.GetIterator();
|
||||||
|
PSymbolTable::MapType::Pair *pair;
|
||||||
|
while (it.NextPair(pair))
|
||||||
|
{
|
||||||
|
if (!pair->Value->IsKindOf(RUNTIME_CLASS(PField)) && !pair->Value->IsKindOf(RUNTIME_CLASS(PFunction)))
|
||||||
|
{
|
||||||
|
ty->Symbols.RemoveSymbol(pair->Value);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DPrintf(DMSG_SPAMMY, "%d symbols removed after compilation\n", count);
|
||||||
|
}
|
||||||
|
|
|
@ -76,6 +76,7 @@ class VMFrameStack;
|
||||||
struct VMValue;
|
struct VMValue;
|
||||||
struct VMReturn;
|
struct VMReturn;
|
||||||
class VMFunction;
|
class VMFunction;
|
||||||
|
struct FNamespaceManager;
|
||||||
|
|
||||||
// A VM function ------------------------------------------------------------
|
// A VM function ------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -157,6 +158,7 @@ private:
|
||||||
MapType Symbols;
|
MapType Symbols;
|
||||||
|
|
||||||
friend class DObject;
|
friend class DObject;
|
||||||
|
friend struct FNamespaceManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A symbol for a compiler tree node ----------------------------------------
|
// A symbol for a compiler tree node ----------------------------------------
|
||||||
|
@ -1010,6 +1012,7 @@ struct FNamespaceManager
|
||||||
PNamespace *NewNamespace(int filenum);
|
PNamespace *NewNamespace(int filenum);
|
||||||
size_t MarkSymbols();
|
size_t MarkSymbols();
|
||||||
void ReleaseSymbols();
|
void ReleaseSymbols();
|
||||||
|
int RemoveSymbols();
|
||||||
};
|
};
|
||||||
|
|
||||||
extern FNamespaceManager Namespaces;
|
extern FNamespaceManager Namespaces;
|
||||||
|
@ -1047,4 +1050,7 @@ inline T *&DObject::PointerVar(FName field)
|
||||||
{
|
{
|
||||||
return *(T**)ScriptVar(field, nullptr); // pointer check is more tricky and for the handful of uses in the DECORATE parser not worth the hassle.
|
return *(T**)ScriptVar(field, nullptr); // pointer check is more tricky and for the handful of uses in the DECORATE parser not worth the hassle.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RemoveUnusedSymbols();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -9716,7 +9716,16 @@ scriptwait:
|
||||||
|
|
||||||
if (runaway != 0 && InModuleScriptNumber >= 0)
|
if (runaway != 0 && InModuleScriptNumber >= 0)
|
||||||
{
|
{
|
||||||
activeBehavior->GetScriptPtr(InModuleScriptNumber)->ProfileData.AddRun(runaway);
|
auto scriptptr = activeBehavior->GetScriptPtr(InModuleScriptNumber);
|
||||||
|
if (scriptptr != nullptr)
|
||||||
|
{
|
||||||
|
scriptptr->ProfileData.AddRun(runaway);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// It is pointless to continue execution. The script is broken and needs to be aborted.
|
||||||
|
I_Error("Bad script definition encountered. Script %d is reported running but not present.\nThe most likely cause for this message is using 'delay' inside a function which is not supported.\nPlease check the ACS compiler used for compiling the script!", InModuleScriptNumber);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == SCRIPT_DivideBy0)
|
if (state == SCRIPT_DivideBy0)
|
||||||
|
|
|
@ -1613,7 +1613,7 @@ FxExpression *FxTypeCast::Resolve(FCompileContext &ctx)
|
||||||
}
|
}
|
||||||
else if (ValueType->IsKindOf(RUNTIME_CLASS(PClassPointer)))
|
else if (ValueType->IsKindOf(RUNTIME_CLASS(PClassPointer)))
|
||||||
{
|
{
|
||||||
FxExpression *x = new FxClassTypeCast(static_cast<PClassPointer*>(ValueType), basex);
|
FxExpression *x = new FxClassTypeCast(static_cast<PClassPointer*>(ValueType), basex, Explicit);
|
||||||
x = x->Resolve(ctx);
|
x = x->Resolve(ctx);
|
||||||
basex = nullptr;
|
basex = nullptr;
|
||||||
delete this;
|
delete this;
|
||||||
|
@ -4412,7 +4412,7 @@ FxExpression *FxTypeCheck::Resolve(FCompileContext& ctx)
|
||||||
|
|
||||||
if (left->ValueType->IsKindOf(RUNTIME_CLASS(PClassPointer)))
|
if (left->ValueType->IsKindOf(RUNTIME_CLASS(PClassPointer)))
|
||||||
{
|
{
|
||||||
left = new FxClassTypeCast(NewClassPointer(RUNTIME_CLASS(DObject)), left);
|
left = new FxClassTypeCast(NewClassPointer(RUNTIME_CLASS(DObject)), left, false);
|
||||||
ClassCheck = true;
|
ClassCheck = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -4420,7 +4420,7 @@ FxExpression *FxTypeCheck::Resolve(FCompileContext& ctx)
|
||||||
left = new FxTypeCast(left, NewPointer(RUNTIME_CLASS(DObject)), false);
|
left = new FxTypeCast(left, NewPointer(RUNTIME_CLASS(DObject)), false);
|
||||||
ClassCheck = false;
|
ClassCheck = false;
|
||||||
}
|
}
|
||||||
right = new FxClassTypeCast(NewClassPointer(RUNTIME_CLASS(DObject)), right);
|
right = new FxClassTypeCast(NewClassPointer(RUNTIME_CLASS(DObject)), right, false);
|
||||||
|
|
||||||
RESOLVE(left, ctx);
|
RESOLVE(left, ctx);
|
||||||
RESOLVE(right, ctx);
|
RESOLVE(right, ctx);
|
||||||
|
@ -9922,12 +9922,13 @@ VMFunction *FxReturnStatement::GetDirectFunction()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
FxClassTypeCast::FxClassTypeCast(PClassPointer *dtype, FxExpression *x)
|
FxClassTypeCast::FxClassTypeCast(PClassPointer *dtype, FxExpression *x, bool explicitily)
|
||||||
: FxExpression(EFX_ClassTypeCast, x->ScriptPosition)
|
: FxExpression(EFX_ClassTypeCast, x->ScriptPosition)
|
||||||
{
|
{
|
||||||
ValueType = dtype;
|
ValueType = dtype;
|
||||||
desttype = dtype->ClassRestriction;
|
desttype = dtype->ClassRestriction;
|
||||||
basex=x;
|
basex=x;
|
||||||
|
Explicit = explicitily;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -9991,7 +9992,9 @@ FxExpression *FxClassTypeCast::Resolve(FCompileContext &ctx)
|
||||||
|
|
||||||
if (clsname != NAME_None)
|
if (clsname != NAME_None)
|
||||||
{
|
{
|
||||||
cls = FindClassType(clsname, ctx);
|
if (Explicit) cls = FindClassType(clsname, ctx);
|
||||||
|
else cls = PClass::FindClass(clsname);
|
||||||
|
|
||||||
if (cls == nullptr)
|
if (cls == nullptr)
|
||||||
{
|
{
|
||||||
/* lax */
|
/* lax */
|
||||||
|
@ -10141,7 +10144,7 @@ FxExpression *FxClassPtrCast::Resolve(FCompileContext &ctx)
|
||||||
}
|
}
|
||||||
else if (basex->ValueType == TypeString || basex->ValueType == TypeName)
|
else if (basex->ValueType == TypeString || basex->ValueType == TypeName)
|
||||||
{
|
{
|
||||||
FxExpression *x = new FxClassTypeCast(to, basex);
|
FxExpression *x = new FxClassTypeCast(to, basex, true);
|
||||||
basex = nullptr;
|
basex = nullptr;
|
||||||
delete this;
|
delete this;
|
||||||
return x->Resolve(ctx);
|
return x->Resolve(ctx);
|
||||||
|
|
|
@ -1913,10 +1913,11 @@ class FxClassTypeCast : public FxExpression
|
||||||
{
|
{
|
||||||
PClass *desttype;
|
PClass *desttype;
|
||||||
FxExpression *basex;
|
FxExpression *basex;
|
||||||
|
bool Explicit;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
FxClassTypeCast(PClassPointer *dtype, FxExpression *x);
|
FxClassTypeCast(PClassPointer *dtype, FxExpression *x, bool explicitly);
|
||||||
~FxClassTypeCast();
|
~FxClassTypeCast();
|
||||||
FxExpression *Resolve(FCompileContext&);
|
FxExpression *Resolve(FCompileContext&);
|
||||||
ExpEmit Emit(VMFunctionBuilder *build);
|
ExpEmit Emit(VMFunctionBuilder *build);
|
||||||
|
|
|
@ -197,7 +197,7 @@ FxExpression *ParseParameter(FScanner &sc, PClassActor *cls, PType *type)
|
||||||
sc.SetEscape(true);
|
sc.SetEscape(true);
|
||||||
sc.MustGetString();
|
sc.MustGetString();
|
||||||
sc.SetEscape(false);
|
sc.SetEscape(false);
|
||||||
x = new FxClassTypeCast(static_cast<PClassPointer *>(type), new FxConstant(FName(sc.String), sc));
|
x = new FxClassTypeCast(static_cast<PClassPointer *>(type), new FxConstant(FName(sc.String), sc), false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue