- added a new variable flag that allows defining variables which can only be modified by internal script code but not by external mods. Currently this is used by the NoBlockmap and NoSector flags which need special handling for changing.

This commit is contained in:
Christoph Oelckers 2016-11-08 11:12:56 +01:00
parent 3661e479d9
commit 7b7b66d8b7
9 changed files with 67 additions and 43 deletions

View file

@ -30,6 +30,7 @@ enum
VARF_Out = (1<<11), VARF_Out = (1<<11),
VARF_Implicit = (1<<12), // implicitly created parameters (i.e. do not compare types when checking function signatures) VARF_Implicit = (1<<12), // implicitly created parameters (i.e. do not compare types when checking function signatures)
VARF_Static = (1<<13), // static class data (by necessity read only.) VARF_Static = (1<<13), // static class data (by necessity read only.)
VARF_InternalAccess = (1<<14), // overrides VARF_ReadOnly for internal script code.
}; };
// Symbol information ------------------------------------------------------- // Symbol information -------------------------------------------------------

View file

@ -53,6 +53,7 @@
#include "m_fixed.h" #include "m_fixed.h"
#include "vmbuilder.h" #include "vmbuilder.h"
#include "v_text.h" #include "v_text.h"
#include "w_wad.h"
#include "math/cmath.h" #include "math/cmath.h"
extern FRandom pr_exrandom; extern FRandom pr_exrandom;
@ -93,14 +94,14 @@ static const FLOP FxFlops[] =
// //
//========================================================================== //==========================================================================
FCompileContext::FCompileContext(PFunction *fnc, PPrototype *ret, bool fromdecorate, int stateindex, int statecount) FCompileContext::FCompileContext(PFunction *fnc, PPrototype *ret, bool fromdecorate, int stateindex, int statecount, int lump)
: ReturnProto(ret), Function(fnc), Class(nullptr), FromDecorate(fromdecorate), StateIndex(stateindex), StateCount(statecount) : ReturnProto(ret), Function(fnc), Class(nullptr), FromDecorate(fromdecorate), StateIndex(stateindex), StateCount(statecount), Lump(lump)
{ {
if (fnc != nullptr) Class = fnc->OwningClass; if (fnc != nullptr) Class = fnc->OwningClass;
} }
FCompileContext::FCompileContext(PClass *cls, bool fromdecorate) FCompileContext::FCompileContext(PClass *cls, bool fromdecorate)
: ReturnProto(nullptr), Function(nullptr), Class(cls), FromDecorate(fromdecorate), StateIndex(-1), StateCount(0) : ReturnProto(nullptr), Function(nullptr), Class(cls), FromDecorate(fromdecorate), StateIndex(-1), StateCount(0), Lump(-1)
{ {
} }
@ -164,6 +165,13 @@ void FCompileContext::CheckReturn(PPrototype *proto, FScriptPosition &pos)
} }
} }
bool FCompileContext::CheckReadOnly(int flags)
{
if (!(flags & VARF_ReadOnly)) return false;
if (!(flags & VARF_InternalAccess)) return true;
return Wads.GetLumpFile(Lump) != 0;
}
FxLocalVariableDeclaration *FCompileContext::FindLocalVariable(FName name) FxLocalVariableDeclaration *FCompileContext::FindLocalVariable(FName name)
{ {
if (Block == nullptr) if (Block == nullptr)
@ -307,7 +315,7 @@ FxExpression *FxExpression::Resolve(FCompileContext &ctx)
// //
//========================================================================== //==========================================================================
bool FxExpression::RequestAddress(bool *writable) bool FxExpression::RequestAddress(FCompileContext &ctx, bool *writable)
{ {
if (writable != nullptr) *writable = false; if (writable != nullptr) *writable = false;
return false; return false;
@ -1178,10 +1186,20 @@ FxExpression *FxColorCast::Resolve(FCompileContext &ctx)
if (basex->isConstant()) if (basex->isConstant())
{ {
ExpVal constval = static_cast<FxConstant *>(basex)->GetValue(); ExpVal constval = static_cast<FxConstant *>(basex)->GetValue();
if (constval.GetString().Len() == 0)
{
// empty string means 'no state'. This would otherwise just cause endless errors and have the same result anyway.
FxExpression *x = new FxConstant(-1, ScriptPosition);
delete this;
return x;
}
else
{
FxExpression *x = new FxConstant(V_GetColor(nullptr, constval.GetString()), ScriptPosition); FxExpression *x = new FxConstant(V_GetColor(nullptr, constval.GetString()), ScriptPosition);
delete this; delete this;
return x; return x;
} }
}
return this; return this;
} }
else else
@ -1870,7 +1888,7 @@ FxExpression *FxSizeAlign::Resolve(FCompileContext& ctx)
delete this; delete this;
return nullptr; return nullptr;
} }
else if (!Operand->RequestAddress(nullptr)) else if (!Operand->RequestAddress(ctx, nullptr))
{ {
ScriptPosition.Message(MSG_ERROR, "Operand must be addressable to determine %s", Which == TK_AlignOf ? "alignment" : "size"); ScriptPosition.Message(MSG_ERROR, "Operand must be addressable to determine %s", Which == TK_AlignOf ? "alignment" : "size");
delete this; delete this;
@ -1907,7 +1925,7 @@ FxPreIncrDecr::~FxPreIncrDecr()
SAFE_DELETE(Base); SAFE_DELETE(Base);
} }
bool FxPreIncrDecr::RequestAddress(bool *writable) bool FxPreIncrDecr::RequestAddress(FCompileContext &ctx, bool *writable)
{ {
AddressRequested = true; AddressRequested = true;
if (writable != nullptr) *writable = AddressWritable; if (writable != nullptr) *writable = AddressWritable;
@ -1933,7 +1951,7 @@ FxExpression *FxPreIncrDecr::Resolve(FCompileContext &ctx)
delete this; delete this;
return nullptr; return nullptr;
} }
if (!Base->RequestAddress(&AddressWritable) || !AddressWritable ) if (!Base->RequestAddress(ctx, &AddressWritable) || !AddressWritable )
{ {
ScriptPosition.Message(MSG_ERROR, "Expression must be a modifiable value"); ScriptPosition.Message(MSG_ERROR, "Expression must be a modifiable value");
delete this; delete this;
@ -2019,7 +2037,7 @@ FxExpression *FxPostIncrDecr::Resolve(FCompileContext &ctx)
delete this; delete this;
return nullptr; return nullptr;
} }
if (!Base->RequestAddress(&AddressWritable) || !AddressWritable) if (!Base->RequestAddress(ctx, &AddressWritable) || !AddressWritable)
{ {
ScriptPosition.Message(MSG_ERROR, "Expression must be a modifiable value"); ScriptPosition.Message(MSG_ERROR, "Expression must be a modifiable value");
delete this; delete this;
@ -2107,7 +2125,7 @@ FxAssign::~FxAssign()
} }
/* I don't think we should allow constructs like (a = b) = c;... /* I don't think we should allow constructs like (a = b) = c;...
bool FxAssign::RequestAddress(bool *writable) bool FxAssign::RequestAddress(FCompileContext &ctx, bool *writable)
{ {
AddressRequested = true; AddressRequested = true;
if (writable != nullptr) *writable = AddressWritable; if (writable != nullptr) *writable = AddressWritable;
@ -2177,7 +2195,7 @@ FxExpression *FxAssign::Resolve(FCompileContext &ctx)
SAFE_RESOLVE(Right, ctx); SAFE_RESOLVE(Right, ctx);
} }
if (!Base->RequestAddress(&AddressWritable) || !AddressWritable) if (!Base->RequestAddress(ctx, &AddressWritable) || !AddressWritable)
{ {
ScriptPosition.Message(MSG_ERROR, "Expression must be a modifiable value"); ScriptPosition.Message(MSG_ERROR, "Expression must be a modifiable value");
delete this; delete this;
@ -2188,7 +2206,7 @@ FxExpression *FxAssign::Resolve(FCompileContext &ctx)
if (Base->ExprType == EFX_StructMember || Base->ExprType == EFX_ClassMember) if (Base->ExprType == EFX_StructMember || Base->ExprType == EFX_ClassMember)
{ {
auto f = static_cast<FxStructMember *>(Base)->membervar; auto f = static_cast<FxStructMember *>(Base)->membervar;
if (f->BitValue != -1 && !(f->Flags & VARF_ReadOnly)) if (f->BitValue != -1 && !ctx.CheckReadOnly(f->Flags))
{ {
IsBitWrite = f->BitValue; IsBitWrite = f->BitValue;
return this; return this;
@ -5335,10 +5353,10 @@ FxExpression *FxLocalVariable::Resolve(FCompileContext &ctx)
return this; return this;
} }
bool FxLocalVariable::RequestAddress(bool *writable) bool FxLocalVariable::RequestAddress(FCompileContext &ctx, bool *writable)
{ {
AddressRequested = true; AddressRequested = true;
if (writable != nullptr) *writable = !(Variable->VarFlags & VARF_ReadOnly); if (writable != nullptr) *writable = !ctx.CheckReadOnly(Variable->VarFlags);
return true; return true;
} }
@ -5504,10 +5522,10 @@ FxGlobalVariable::FxGlobalVariable(PField* mem, const FScriptPosition &pos)
// //
//========================================================================== //==========================================================================
bool FxGlobalVariable::RequestAddress(bool *writable) bool FxGlobalVariable::RequestAddress(FCompileContext &ctx, bool *writable)
{ {
AddressRequested = true; AddressRequested = true;
if (writable != nullptr) *writable = AddressWritable && !(membervar->Flags & VARF_ReadOnly); if (writable != nullptr) *writable = AddressWritable && !ctx.CheckReadOnly(membervar->Flags);
return true; return true;
} }
@ -5582,10 +5600,10 @@ FxStructMember::~FxStructMember()
// //
//========================================================================== //==========================================================================
bool FxStructMember::RequestAddress(bool *writable) bool FxStructMember::RequestAddress(FCompileContext &ctx, bool *writable)
{ {
AddressRequested = true; AddressRequested = true;
if (writable != nullptr) *writable = (AddressWritable && !(membervar->Flags & VARF_ReadOnly) && if (writable != nullptr) *writable = (AddressWritable && !ctx.CheckReadOnly(membervar->Flags) &&
(!classx->ValueType->IsKindOf(RUNTIME_CLASS(PPointer)) || !static_cast<PPointer*>(classx->ValueType)->IsConst)); (!classx->ValueType->IsKindOf(RUNTIME_CLASS(PPointer)) || !static_cast<PPointer*>(classx->ValueType)->IsConst));
return true; return true;
} }
@ -5662,7 +5680,7 @@ FxExpression *FxStructMember::Resolve(FCompileContext &ctx)
} }
else else
{ {
if (!(classx->RequestAddress(&AddressWritable))) if (!(classx->RequestAddress(ctx, &AddressWritable)))
{ {
ScriptPosition.Message(MSG_ERROR, "unable to dereference left side of %s", membervar->SymbolName.GetChars()); ScriptPosition.Message(MSG_ERROR, "unable to dereference left side of %s", membervar->SymbolName.GetChars());
delete this; delete this;
@ -5767,7 +5785,7 @@ FxArrayElement::~FxArrayElement()
// //
//========================================================================== //==========================================================================
bool FxArrayElement::RequestAddress(bool *writable) bool FxArrayElement::RequestAddress(FCompileContext &ctx, bool *writable)
{ {
AddressRequested = true; AddressRequested = true;
if (writable != nullptr) *writable = AddressWritable; if (writable != nullptr) *writable = AddressWritable;
@ -5830,7 +5848,7 @@ FxExpression *FxArrayElement::Resolve(FCompileContext &ctx)
delete this; delete this;
return nullptr; return nullptr;
} }
if (!Array->RequestAddress(&AddressWritable)) if (!Array->RequestAddress(ctx, &AddressWritable))
{ {
ScriptPosition.Message(MSG_ERROR, "Unable to dereference array."); ScriptPosition.Message(MSG_ERROR, "Unable to dereference array.");
delete this; delete this;

View file

@ -76,9 +76,10 @@ struct FCompileContext
bool FromDecorate; // DECORATE must silence some warnings and demote some errors. bool FromDecorate; // DECORATE must silence some warnings and demote some errors.
int StateIndex; // index in actor's state table for anonymous functions, otherwise -1 (not used by DECORATE which pre-resolves state indices) int StateIndex; // index in actor's state table for anonymous functions, otherwise -1 (not used by DECORATE which pre-resolves state indices)
int StateCount; // amount of states an anoymous function is being used on (must be 1 for state indices to be allowed.) int StateCount; // amount of states an anoymous function is being used on (must be 1 for state indices to be allowed.)
int Lump;
TDeletingArray<FxLocalVariableDeclaration *> FunctionArgs; TDeletingArray<FxLocalVariableDeclaration *> FunctionArgs;
FCompileContext(PFunction *func, PPrototype *ret, bool fromdecorate, int stateindex, int statecount); FCompileContext(PFunction *func, PPrototype *ret, bool fromdecorate, int stateindex, int statecount, int lump);
FCompileContext(PClass *cls, bool fromdecorate); // only to be used to resolve constants! FCompileContext(PClass *cls, bool fromdecorate); // only to be used to resolve constants!
PSymbol *FindInClass(FName identifier, PSymbolTable *&symt); PSymbol *FindInClass(FName identifier, PSymbolTable *&symt);
@ -87,6 +88,7 @@ struct FCompileContext
void HandleJumps(int token, FxExpression *handler); void HandleJumps(int token, FxExpression *handler);
void CheckReturn(PPrototype *proto, FScriptPosition &pos); void CheckReturn(PPrototype *proto, FScriptPosition &pos);
bool CheckReadOnly(int flags);
FxLocalVariableDeclaration *FindLocalVariable(FName name); FxLocalVariableDeclaration *FindLocalVariable(FName name);
}; };
@ -296,7 +298,7 @@ public:
virtual FxExpression *Resolve(FCompileContext &ctx); virtual FxExpression *Resolve(FCompileContext &ctx);
virtual bool isConstant() const; virtual bool isConstant() const;
virtual bool RequestAddress(bool *writable); virtual bool RequestAddress(FCompileContext &ctx, bool *writable);
virtual PPrototype *ReturnProto(); virtual PPrototype *ReturnProto();
virtual VMFunction *GetDirectFunction(); virtual VMFunction *GetDirectFunction();
virtual bool CheckReturn() { return false; } virtual bool CheckReturn() { return false; }
@ -715,7 +717,7 @@ public:
FxPreIncrDecr(FxExpression *base, int token); FxPreIncrDecr(FxExpression *base, int token);
~FxPreIncrDecr(); ~FxPreIncrDecr();
FxExpression *Resolve(FCompileContext&); FxExpression *Resolve(FCompileContext&);
bool RequestAddress(bool *writable); bool RequestAddress(FCompileContext &ctx, bool *writable);
ExpEmit Emit(VMFunctionBuilder *build); ExpEmit Emit(VMFunctionBuilder *build);
}; };
@ -758,7 +760,7 @@ public:
FxAssign(FxExpression *base, FxExpression *right, bool ismodify = false); FxAssign(FxExpression *base, FxExpression *right, bool ismodify = false);
~FxAssign(); ~FxAssign();
FxExpression *Resolve(FCompileContext&); FxExpression *Resolve(FCompileContext&);
//bool RequestAddress(bool *writable); //bool RequestAddress(FCompileContext &ctx, bool *writable);
ExpEmit Emit(VMFunctionBuilder *build); ExpEmit Emit(VMFunctionBuilder *build);
ExpEmit Address; ExpEmit Address;
@ -1157,7 +1159,7 @@ public:
FxGlobalVariable(PField*, const FScriptPosition&); FxGlobalVariable(PField*, const FScriptPosition&);
FxExpression *Resolve(FCompileContext&); FxExpression *Resolve(FCompileContext&);
bool RequestAddress(bool *writable); bool RequestAddress(FCompileContext &ctx, bool *writable);
ExpEmit Emit(VMFunctionBuilder *build); ExpEmit Emit(VMFunctionBuilder *build);
}; };
@ -1178,7 +1180,7 @@ public:
FxStructMember(FxExpression*, PField*, const FScriptPosition&); FxStructMember(FxExpression*, PField*, const FScriptPosition&);
~FxStructMember(); ~FxStructMember();
FxExpression *Resolve(FCompileContext&); FxExpression *Resolve(FCompileContext&);
bool RequestAddress(bool *writable); bool RequestAddress(FCompileContext &ctx, bool *writable);
ExpEmit Emit(VMFunctionBuilder *build); ExpEmit Emit(VMFunctionBuilder *build);
}; };
@ -1210,7 +1212,7 @@ public:
FxLocalVariable(FxLocalVariableDeclaration*, const FScriptPosition&); FxLocalVariable(FxLocalVariableDeclaration*, const FScriptPosition&);
FxExpression *Resolve(FCompileContext&); FxExpression *Resolve(FCompileContext&);
bool RequestAddress(bool *writable); bool RequestAddress(FCompileContext &ctx, bool *writable);
ExpEmit Emit(VMFunctionBuilder *build); ExpEmit Emit(VMFunctionBuilder *build);
}; };
@ -1245,7 +1247,7 @@ public:
FxArrayElement(FxExpression*, FxExpression*); FxArrayElement(FxExpression*, FxExpression*);
~FxArrayElement(); ~FxArrayElement();
FxExpression *Resolve(FCompileContext&); FxExpression *Resolve(FCompileContext&);
bool RequestAddress(bool *writable); bool RequestAddress(FCompileContext &ctx, bool *writable);
ExpEmit Emit(VMFunctionBuilder *build); ExpEmit Emit(VMFunctionBuilder *build);
}; };

View file

@ -55,7 +55,7 @@ static TArray<AFuncDesc> AFTable;
// [RH] Keep GCC quiet by not using offsetof on Actor types. // [RH] Keep GCC quiet by not using offsetof on Actor types.
#define DEFINE_FLAG(prefix, name, type, variable) { (unsigned int)prefix##_##name, #name, (int)(size_t)&((type*)1)->variable - 1, sizeof(((type *)0)->variable), VARF_Native } #define DEFINE_FLAG(prefix, name, type, variable) { (unsigned int)prefix##_##name, #name, (int)(size_t)&((type*)1)->variable - 1, sizeof(((type *)0)->variable), VARF_Native }
#define DEFINE_READONLY_FLAG(prefix, name, type, variable) { (unsigned int)prefix##_##name, #name, (int)(size_t)&((type*)1)->variable - 1, sizeof(((type *)0)->variable), VARF_Native|VARF_ReadOnly } #define DEFINE_PROTECTED_FLAG(prefix, name, type, variable) { (unsigned int)prefix##_##name, #name, (int)(size_t)&((type*)1)->variable - 1, sizeof(((type *)0)->variable), VARF_Native|VARF_ReadOnly|VARF_InternalAccess }
#define DEFINE_FLAG2(symbol, name, type, variable) { (unsigned int)symbol, #name, (int)(size_t)&((type*)1)->variable - 1, sizeof(((type *)0)->variable), VARF_Native } #define DEFINE_FLAG2(symbol, name, type, variable) { (unsigned int)symbol, #name, (int)(size_t)&((type*)1)->variable - 1, sizeof(((type *)0)->variable), VARF_Native }
#define DEFINE_FLAG2_DEPRECATED(symbol, name, type, variable) { (unsigned int)symbol, #name, (int)(size_t)&((type*)1)->variable - 1, sizeof(((type *)0)->variable), VARF_Native|VARF_Deprecated } #define DEFINE_FLAG2_DEPRECATED(symbol, name, type, variable) { (unsigned int)symbol, #name, (int)(size_t)&((type*)1)->variable - 1, sizeof(((type *)0)->variable), VARF_Native|VARF_Deprecated }
#define DEFINE_DEPRECATED_FLAG(name) { DEPF_##name, #name, -1, 0, true } #define DEFINE_DEPRECATED_FLAG(name) { DEPF_##name, #name, -1, 0, true }
@ -99,8 +99,8 @@ FFlagDef ActorFlagDefs[]=
DEFINE_FLAG(MF, SPECIAL, APlayerPawn, flags), DEFINE_FLAG(MF, SPECIAL, APlayerPawn, flags),
DEFINE_FLAG(MF, SOLID, AActor, flags), DEFINE_FLAG(MF, SOLID, AActor, flags),
DEFINE_FLAG(MF, SHOOTABLE, AActor, flags), DEFINE_FLAG(MF, SHOOTABLE, AActor, flags),
DEFINE_FLAG(MF, NOSECTOR, AActor, flags), DEFINE_PROTECTED_FLAG(MF, NOSECTOR, AActor, flags),
DEFINE_FLAG(MF, NOBLOCKMAP, AActor, flags), DEFINE_PROTECTED_FLAG(MF, NOBLOCKMAP, AActor, flags),
DEFINE_FLAG(MF, AMBUSH, AActor, flags), DEFINE_FLAG(MF, AMBUSH, AActor, flags),
DEFINE_FLAG(MF, JUSTHIT, AActor, flags), DEFINE_FLAG(MF, JUSTHIT, AActor, flags),
DEFINE_FLAG(MF, JUSTATTACKED, AActor, flags), DEFINE_FLAG(MF, JUSTATTACKED, AActor, flags),

View file

@ -653,7 +653,7 @@ void VMFunctionBuilder::BackpatchToHere(size_t loc)
//========================================================================== //==========================================================================
FFunctionBuildList FunctionBuildList; FFunctionBuildList FunctionBuildList;
VMFunction *FFunctionBuildList::AddFunction(PFunction *functype, FxExpression *code, const FString &name, bool fromdecorate, int stateindex, int statecount) VMFunction *FFunctionBuildList::AddFunction(PFunction *functype, FxExpression *code, const FString &name, bool fromdecorate, int stateindex, int statecount, int lumpnum)
{ {
auto func = code->GetDirectFunction(); auto func = code->GetDirectFunction();
if (func != nullptr) if (func != nullptr)
@ -675,6 +675,7 @@ VMFunction *FFunctionBuildList::AddFunction(PFunction *functype, FxExpression *c
it.FromDecorate = fromdecorate; it.FromDecorate = fromdecorate;
it.StateIndex = stateindex; it.StateIndex = stateindex;
it.StateCount = statecount; it.StateCount = statecount;
it.Lump = lumpnum;
// set prototype for named functions. // set prototype for named functions.
if (it.Func->SymbolName != NAME_None) if (it.Func->SymbolName != NAME_None)
@ -700,7 +701,7 @@ void FFunctionBuildList::Build()
assert(item.Code != NULL); assert(item.Code != NULL);
// We don't know the return type in advance for anonymous functions. // We don't know the return type in advance for anonymous functions.
FCompileContext ctx(item.Func, item.Func->SymbolName == NAME_None ? nullptr : item.Func->Variants[0].Proto, item.FromDecorate, item.StateIndex, item.StateCount); FCompileContext ctx(item.Func, item.Func->SymbolName == NAME_None ? nullptr : item.Func->Variants[0].Proto, item.FromDecorate, item.StateIndex, item.StateCount, item.Lump);
// Allocate registers for the function's arguments and create local variable nodes before starting to resolve it. // Allocate registers for the function's arguments and create local variable nodes before starting to resolve it.
VMFunctionBuilder buildit(item.Func->GetImplicitArgs()); VMFunctionBuilder buildit(item.Func->GetImplicitArgs());

View file

@ -108,13 +108,14 @@ class FFunctionBuildList
FString PrintableName; FString PrintableName;
int StateIndex; int StateIndex;
int StateCount; int StateCount;
int Lump;
bool FromDecorate; bool FromDecorate;
}; };
TArray<Item> mItems; TArray<Item> mItems;
public: public:
VMFunction *AddFunction(PFunction *func, FxExpression *code, const FString &name, bool fromdecorate, int currentstate = -1, int statecnt = 0); VMFunction *AddFunction(PFunction *func, FxExpression *code, const FString &name, bool fromdecorate, int currentstate = -1, int statecnt = 0, int lumpnum = -1);
void Build(); void Build();
}; };

View file

@ -217,8 +217,8 @@ void ZCCCompiler::ProcessStruct(ZCC_Struct *cnode, PSymbolTreeNode *treenode, ZC
// //
//========================================================================== //==========================================================================
ZCCCompiler::ZCCCompiler(ZCC_AST &ast, DObject *_outer, PSymbolTable &_symbols, PSymbolTable &_outsymbols) ZCCCompiler::ZCCCompiler(ZCC_AST &ast, DObject *_outer, PSymbolTable &_symbols, PSymbolTable &_outsymbols, int lumpnum)
: Outer(_outer), GlobalTreeNodes(&_symbols), OutputSymbols(&_outsymbols), AST(ast) : Outer(_outer), GlobalTreeNodes(&_symbols), OutputSymbols(&_outsymbols), AST(ast), Lump(lumpnum)
{ {
FScriptPosition::ResetErrorCounter(); FScriptPosition::ResetErrorCounter();
// Group top-level nodes by type // Group top-level nodes by type
@ -2146,7 +2146,7 @@ void ZCCCompiler::InitFunctions()
auto code = ConvertAST(c->Type(), f->Body); auto code = ConvertAST(c->Type(), f->Body);
if (code != nullptr) if (code != nullptr)
{ {
sym->Variants[0].Implementation = FunctionBuildList.AddFunction(sym, code, FStringf("%s.%s", c->Type()->TypeName.GetChars(), FName(f->Name).GetChars()), false); sym->Variants[0].Implementation = FunctionBuildList.AddFunction(sym, code, FStringf("%s.%s", c->Type()->TypeName.GetChars(), FName(f->Name).GetChars()), false, -1, 0, Lump);
} }
} }
if (sym->Variants[0].Implementation != nullptr && hasdefault) // do not copy empty default lists, they only waste space and processing time. if (sym->Variants[0].Implementation != nullptr && hasdefault) // do not copy empty default lists, they only waste space and processing time.
@ -2344,7 +2344,7 @@ void ZCCCompiler::CompileStates()
if (code != nullptr) if (code != nullptr)
{ {
auto funcsym = CreateAnonymousFunction(c->Type(), nullptr, VARF_Method | VARF_Action); auto funcsym = CreateAnonymousFunction(c->Type(), nullptr, VARF_Method | VARF_Action);
state.ActionFunc = FunctionBuildList.AddFunction(funcsym, code, FStringf("%s.StateFunction.%d", c->Type()->TypeName.GetChars(), statedef.GetStateCount()), false, statedef.GetStateCount(), (int)sl->Frames->Len()); state.ActionFunc = FunctionBuildList.AddFunction(funcsym, code, FStringf("%s.StateFunction.%d", c->Type()->TypeName.GetChars(), statedef.GetStateCount()), false, statedef.GetStateCount(), (int)sl->Frames->Len(), Lump);
} }
} }

View file

@ -78,7 +78,7 @@ struct ZCC_ConstantWork
class ZCCCompiler class ZCCCompiler
{ {
public: public:
ZCCCompiler(ZCC_AST &tree, DObject *outer, PSymbolTable &symbols, PSymbolTable &outsymbols); ZCCCompiler(ZCC_AST &tree, DObject *outer, PSymbolTable &symbols, PSymbolTable &outsymbols, int lumpnum);
~ZCCCompiler(); ~ZCCCompiler();
int Compile(); int Compile();
@ -149,6 +149,7 @@ private:
PSymbolTable *GlobalTreeNodes; PSymbolTable *GlobalTreeNodes;
PSymbolTable *OutputSymbols; PSymbolTable *OutputSymbols;
ZCC_AST &AST; ZCC_AST &AST;
int Lump;
}; };
void ZCC_InitConversions(); void ZCC_InitConversions();

View file

@ -374,7 +374,7 @@ static void DoParse(int lumpnum)
PSymbolTable symtable; PSymbolTable symtable;
symtable.SetName("Global_Node"); symtable.SetName("Global_Node");
ZCCCompiler cc(state, NULL, symtable, GlobalSymbols); ZCCCompiler cc(state, NULL, symtable, GlobalSymbols, lumpnum);
cc.Compile(); cc.Compile();
if (FScriptPosition::ErrorCounter > 0) if (FScriptPosition::ErrorCounter > 0)