- added a FindSymbol wrapper to PClass so that other code does not need to access the symbol table directly.

- added an isActor utility function to codegen.cpp to simplify a few constructs.
This commit is contained in:
Christoph Oelckers 2017-04-12 13:08:41 +02:00
parent b17ab7a133
commit 6308251084
19 changed files with 49 additions and 38 deletions

View file

@ -33,7 +33,6 @@
// States are tied to finite states are tied to animation frames.
#include "info.h"
#include <forward_list>
#include "doomdef.h"
#include "textures/textures.h"
#include "r_data/renderstyle.h"

View file

@ -791,7 +791,7 @@ void SetDehParams(FState *state, int codepointer)
// Let's identify the codepointer we're dealing with.
PFunction *sym;
sym = dyn_cast<PFunction>(RUNTIME_CLASS(AWeapon)->Symbols.FindSymbol(FName(MBFCodePointers[codepointer].name), true));
sym = dyn_cast<PFunction>(RUNTIME_CLASS(AWeapon)->FindSymbol(FName(MBFCodePointers[codepointer].name), true));
if (sym == NULL) return;
if (codepointer < 0 || (unsigned)codepointer >= countof(MBFCodePointerFactories))
@ -2118,7 +2118,7 @@ static int PatchCodePtrs (int dummy)
// This skips the action table and goes directly to the internal symbol table
// DEH compatible functions are easy to recognize.
PFunction *sym = dyn_cast<PFunction>(RUNTIME_CLASS(AWeapon)->Symbols.FindSymbol(symname, true));
PFunction *sym = dyn_cast<PFunction>(RUNTIME_CLASS(AWeapon)->FindSymbol(symname, true));
if (sym == NULL)
{
Printf(TEXTCOLOR_RED "Frame %d: Unknown code pointer '%s'\n", frame, Line2);
@ -2744,7 +2744,7 @@ static bool LoadDehSupp ()
// or AActor so this will find all of them.
FString name = "A_";
name << sc.String;
PFunction *sym = dyn_cast<PFunction>(RUNTIME_CLASS(AWeapon)->Symbols.FindSymbol(name, true));
PFunction *sym = dyn_cast<PFunction>(RUNTIME_CLASS(AWeapon)->FindSymbol(name, true));
if (sym == NULL)
{
sc.ScriptError("Unknown code pointer '%s'", sc.String);
@ -3116,7 +3116,7 @@ void FinishDehPatch ()
{
if (AmmoPerAttacks[j].ptr == nullptr)
{
auto p = dyn_cast<PFunction>(RUNTIME_CLASS(AWeapon)->Symbols.FindSymbol(AmmoPerAttacks[j].func, true));
auto p = dyn_cast<PFunction>(RUNTIME_CLASS(AWeapon)->FindSymbol(AmmoPerAttacks[j].func, true));
if (p != nullptr) AmmoPerAttacks[j].ptr = p->Variants[0].Implementation;
}
if (state->ActionFunc == AmmoPerAttacks[j].ptr)

View file

@ -625,7 +625,7 @@ DEFINE_ACTION_FUNCTION(DObject, MSTime)
void *DObject::ScriptVar(FName field, PType *type)
{
auto cls = GetClass();
auto sym = dyn_cast<PField>(cls->Symbols.FindSymbol(field, true));
auto sym = dyn_cast<PField>(cls->FindSymbol(field, true));
if (sym && (sym->Type == type || type == nullptr))
{
if (!(sym->Flags & VARF_Meta))

View file

@ -2088,7 +2088,7 @@ void PDynArray::SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffs
void PDynArray::SetPointerArray(void *base, unsigned offset, TArray<size_t> *special) const
{
if (ElementType->IsKindOf(RUNTIME_CLASS(PPointer)) && !ElementType->IsKindOf(RUNTIME_CLASS(PClassPointer)) && static_cast<PPointer*>(ElementType)->PointedType->IsKindOf(RUNTIME_CLASS(PClass)))
if (ElementType->IsKindOf(RUNTIME_CLASS(PObjectPointer)))
{
// Add to the list of pointer arrays for this class.
special->Push(offset);
@ -3554,6 +3554,11 @@ int PClass::FindVirtualIndex(FName name, PPrototype *proto)
return -1;
}
PSymbol *PClass::FindSymbol(FName symname, bool searchparents) const
{
return Symbols.FindSymbol(symname, searchparents);
}
//==========================================================================
//
// PClass :: BuildFlatPointers
@ -3722,7 +3727,7 @@ VMFunction *PClass::FindFunction(FName clsname, FName funcname)
{
auto cls = PClass::FindClass(clsname);
if (!cls) return nullptr;
auto func = dyn_cast<PFunction>(cls->Symbols.FindSymbol(funcname, true));
auto func = dyn_cast<PFunction>(cls->FindSymbol(funcname, true));
if (!func) return nullptr;
return func->Variants[0].Implementation;
}
@ -3731,7 +3736,7 @@ void PClass::FindFunction(VMFunction **pptr, FName clsname, FName funcname)
{
auto cls = PClass::FindClass(clsname);
if (!cls) return;
auto func = dyn_cast<PFunction>(cls->Symbols.FindSymbol(funcname, true));
auto func = dyn_cast<PFunction>(cls->FindSymbol(funcname, true));
if (!func) return;
*pptr = func->Variants[0].Implementation;
FunctionPtrList.Push(pptr);

View file

@ -614,6 +614,7 @@ public:
bool ReadAllFields(FSerializer &ar, void *addr) const;
void InitializeDefaults();
int FindVirtualIndex(FName name, PPrototype *proto);
PSymbol *FindSymbol(FName symname, bool searchparents) const;
static void StaticInit();
static void StaticShutdown();

View file

@ -1127,7 +1127,7 @@ DMenuItemBase * CreateOptionMenuItemStaticText(const char *name, bool v)
auto p = c->CreateNew();
FString namestr = name;
VMValue params[] = { p, &namestr, v };
auto f = dyn_cast<PFunction>(c->Symbols.FindSymbol("Init", false));
auto f = dyn_cast<PFunction>(c->FindSymbol("Init", false));
GlobalVMStack.Call(f->Variants[0].Implementation, params, countof(params), nullptr, 0);
return (DMenuItemBase*)p;
}
@ -1138,7 +1138,7 @@ DMenuItemBase * CreateOptionMenuItemJoyConfigMenu(const char *label, IJoystickCo
auto p = c->CreateNew();
FString namestr = label;
VMValue params[] = { p, &namestr, joy };
auto f = dyn_cast<PFunction>(c->Symbols.FindSymbol("Init", false));
auto f = dyn_cast<PFunction>(c->FindSymbol("Init", false));
GlobalVMStack.Call(f->Variants[0].Implementation, params, countof(params), nullptr, 0);
return (DMenuItemBase*)p;
}
@ -1149,7 +1149,7 @@ DMenuItemBase * CreateOptionMenuItemSubmenu(const char *label, FName cmd, int ce
auto p = c->CreateNew();
FString namestr = label;
VMValue params[] = { p, &namestr, cmd.GetIndex(), center };
auto f = dyn_cast<PFunction>(c->Symbols.FindSymbol("Init", false));
auto f = dyn_cast<PFunction>(c->FindSymbol("Init", false));
GlobalVMStack.Call(f->Variants[0].Implementation, params, countof(params), nullptr, 0);
return (DMenuItemBase*)p;
}
@ -1160,7 +1160,7 @@ DMenuItemBase * CreateOptionMenuItemControl(const char *label, FName cmd, FKeyBi
auto p = c->CreateNew();
FString namestr = label;
VMValue params[] = { p, &namestr, cmd.GetIndex(), bindings };
auto f = dyn_cast<PFunction>(c->Symbols.FindSymbol("Init", false));
auto f = dyn_cast<PFunction>(c->FindSymbol("Init", false));
GlobalVMStack.Call(f->Variants[0].Implementation, params, countof(params), nullptr, 0);
return (DMenuItemBase*)p;
}
@ -1171,7 +1171,7 @@ DMenuItemBase * CreateListMenuItemPatch(double x, double y, int height, int hotk
auto p = c->CreateNew();
FString keystr = FString(char(hotkey));
VMValue params[] = { p, x, y, height, tex.GetIndex(), &keystr, command.GetIndex(), param };
auto f = dyn_cast<PFunction>(c->Symbols.FindSymbol("InitDirect", false));
auto f = dyn_cast<PFunction>(c->FindSymbol("InitDirect", false));
GlobalVMStack.Call(f->Variants[0].Implementation, params, countof(params), nullptr, 0);
return (DMenuItemBase*)p;
}
@ -1183,7 +1183,7 @@ DMenuItemBase * CreateListMenuItemText(double x, double y, int height, int hotke
FString keystr = FString(char(hotkey));
FString textstr = text;
VMValue params[] = { p, x, y, height, &keystr, &textstr, font, int(color1.d), int(color2.d), command.GetIndex(), param };
auto f = dyn_cast<PFunction>(c->Symbols.FindSymbol("InitDirect", false));
auto f = dyn_cast<PFunction>(c->FindSymbol("InitDirect", false));
GlobalVMStack.Call(f->Variants[0].Implementation, params, countof(params), nullptr, 0);
return (DMenuItemBase*)p;
}

View file

@ -371,7 +371,7 @@ static void ParseListMenuBody(FScanner &sc, DListMenuDescriptor *desc)
PClass *cls = PClass::FindClass(buildname);
if (cls != nullptr && cls->IsDescendantOf("ListMenuItem"))
{
auto func = dyn_cast<PFunction>(cls->Symbols.FindSymbol("Init", true));
auto func = dyn_cast<PFunction>(cls->FindSymbol("Init", true));
if (func != nullptr && !(func->Variants[0].Flags & (VARF_Protected | VARF_Private))) // skip internal classes which have a protexted init method.
{
auto &args = func->Variants[0].Proto->ArgumentTypes;
@ -746,7 +746,7 @@ static void ParseOptionMenuBody(FScanner &sc, DOptionMenuDescriptor *desc)
PClass *cls = PClass::FindClass(buildname);
if (cls != nullptr && cls->IsDescendantOf("OptionMenuItem"))
{
auto func = dyn_cast<PFunction>(cls->Symbols.FindSymbol("Init", true));
auto func = dyn_cast<PFunction>(cls->FindSymbol("Init", true));
if (func != nullptr && !(func->Variants[0].Flags & (VARF_Protected | VARF_Private))) // skip internal classes which have a protexted init method.
{
auto &args = func->Variants[0].Proto->ArgumentTypes;

View file

@ -70,7 +70,7 @@ DMenu *CreateMessageBoxMenu(DMenu *parent, const char *message, int messagemode,
FString namestr = message;
VMValue params[] = { p, parent, &namestr, messagemode, playsound, action.GetIndex(), reinterpret_cast<void*>(handler) };
auto f = dyn_cast<PFunction>(c->Symbols.FindSymbol("Init", false));
auto f = dyn_cast<PFunction>(c->FindSymbol("Init", false));
GlobalVMStack.Call(f->Variants[0].Implementation, params, countof(params), nullptr, 0);
return (DMenu*)p;
}

View file

@ -5012,7 +5012,7 @@ int DLevelScript::LineFromID(int id)
bool GetVarAddrType(AActor *self, FName varname, int index, void *&addr, PType *&type, bool readonly)
{
PField *var = dyn_cast<PField>(self->GetClass()->Symbols.FindSymbol(varname, true));
PField *var = dyn_cast<PField>(self->GetClass()->FindSymbol(varname, true));
PArray *arraytype;
if (var == NULL || (!readonly && (var->Flags & VARF_Native)))
@ -5362,7 +5362,7 @@ static int ScriptCall(AActor *activator, unsigned argc, int32_t *args)
{
I_Error("ACS call to unknown class in script function %s.%s", clsname, funcname);
}
auto funcsym = dyn_cast<PFunction>(cls->Symbols.FindSymbol(funcname, true));
auto funcsym = dyn_cast<PFunction>(cls->FindSymbol(funcname, true));
if (funcsym == nullptr)
{
I_Error("ACS call to unknown script function %s.%s", clsname, funcname);

View file

@ -4749,7 +4749,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ChangeVelocity)
static PField *GetVar(DObject *self, FName varname)
{
PField *var = dyn_cast<PField>(self->GetClass()->Symbols.FindSymbol(varname, true));
PField *var = dyn_cast<PField>(self->GetClass()->FindSymbol(varname, true));
if (var == NULL || (var->Flags & (VARF_Native | VARF_Private | VARF_Protected | VARF_Static)) || !var->Type->IsKindOf(RUNTIME_CLASS(PBasicType)))
{
@ -4798,7 +4798,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SetUserVarFloat)
static PField *GetArrayVar(DObject *self, FName varname, int pos)
{
PField *var = dyn_cast<PField>(self->GetClass()->Symbols.FindSymbol(varname, true));
PField *var = dyn_cast<PField>(self->GetClass()->FindSymbol(varname, true));
if (var == NULL || (var->Flags & (VARF_Native | VARF_Private | VARF_Protected | VARF_Static)) ||
!var->Type->IsKindOf(RUNTIME_CLASS(PArray)) ||

View file

@ -1616,7 +1616,7 @@ static void SetMapThingUserData(AActor *actor, unsigned udi)
{
FName varname = MapThingsUserData[udi].Property;
int value = MapThingsUserData[udi].Value;
PField *var = dyn_cast<PField>(actor->GetClass()->Symbols.FindSymbol(varname, true));
PField *var = dyn_cast<PField>(actor->GetClass()->FindSymbol(varname, true));
udi++;

View file

@ -224,6 +224,12 @@ static PClass *FindClassType(FName name, FCompileContext &ctx)
return nullptr;
}
bool isActor(PStruct *type)
{
auto cls = dyn_cast<PClass>(type);
return cls ? cls->IsDescendantOf(RUNTIME_CLASS(AActor)) : false;
}
//==========================================================================
//
// ExpEmit
@ -5963,7 +5969,7 @@ FxExpression *FxIdentifier::Resolve(FCompileContext& ctx)
delete this;
return nullptr;
}
if (!ctx.Function->Variants[0].SelfClass->IsKindOf(RUNTIME_CLASS(PClassActor)))
if (!isActor(ctx.Function->Variants[0].SelfClass))
{
ScriptPosition.Message(MSG_ERROR, "'Default' requires an actor type.");
delete this;
@ -6123,7 +6129,7 @@ FxExpression *FxIdentifier::ResolveMember(FCompileContext &ctx, PStruct *classct
if (Identifier == NAME_Default)
{
if (!objtype->IsKindOf(RUNTIME_CLASS(PClassActor)))
if (!isActor(objtype))
{
ScriptPosition.Message(MSG_ERROR, "'Default' requires an actor type.");
delete object;
@ -7689,7 +7695,7 @@ FxExpression *FxFunctionCall::Resolve(FCompileContext& ctx)
delete this;
return nullptr;
}
FxExpression *self = (ctx.Function && (ctx.Function->Variants[0].Flags & VARF_Method) && ctx.Class->IsKindOf(RUNTIME_CLASS(PClassActor))) ? new FxSelf(ScriptPosition) : (FxExpression*)new FxConstant(ScriptPosition);
FxExpression *self = (ctx.Function && (ctx.Function->Variants[0].Flags & VARF_Method) && isActor(ctx.Class)) ? new FxSelf(ScriptPosition) : (FxExpression*)new FxConstant(ScriptPosition);
FxExpression *x = new FxActionSpecialCall(self, special, ArgList, ScriptPosition);
delete this;
return x->Resolve(ctx);
@ -10693,9 +10699,9 @@ int BuiltinNameToClass(VMValue *param, TArray<VMValue> &defaultparam, int numpar
// Let the caller check this. Making this an error with a message is only taking away options from the user.
cls = nullptr;
}
ret->SetObject(const_cast<PClass *>(cls));
ret->SetPointer(const_cast<PClass *>(cls));
}
else ret->SetObject(nullptr);
else ret->SetPointer(nullptr);
return 1;
}
@ -10810,7 +10816,7 @@ int BuiltinClassCast(VMValue *param, TArray<VMValue> &defaultparam, int numparam
PARAM_PROLOGUE;
PARAM_CLASS(from, DObject);
PARAM_CLASS(to, DObject);
ACTION_RETURN_OBJECT(from && to && from->IsDescendantOf(to) ? from : nullptr);
ACTION_RETURN_POINTER(from && to && from->IsDescendantOf(to) ? from : nullptr);
}
ExpEmit FxClassPtrCast::Emit(VMFunctionBuilder *build)

View file

@ -505,7 +505,7 @@ static FxExpression *ParseExpression0 (FScanner &sc, PClassActor *cls)
default:
if (cls != nullptr)
{
func = dyn_cast<PFunction>(cls->Symbols.FindSymbol(identifier, true));
func = dyn_cast<PFunction>(cls->FindSymbol(identifier, true));
// There is an action function ACS_NamedExecuteWithResult which must be ignored here for this to work.
if (func != nullptr && identifier != NAME_ACS_NamedExecuteWithResult)

View file

@ -964,7 +964,7 @@ static void ParseActorProperty(FScanner &sc, Baggage &bag)
FName name(propname, true);
if (name != NAME_None)
{
auto propp = dyn_cast<PProperty>(bag.Info->Symbols.FindSymbol(name, true));
auto propp = dyn_cast<PProperty>(bag.Info->FindSymbol(name, true));
if (propp != nullptr)
{
DispatchScriptProperty(sc, propp, (AActor *)bag.Info->Defaults, bag);

View file

@ -97,7 +97,7 @@ FxVMFunctionCall *DoActionSpecials(FScanner &sc, FState & state, Baggage &bag)
{
sc.ScriptError ("Too many arguments to %s", specname.GetChars());
}
auto f = dyn_cast<PFunction>(RUNTIME_CLASS(AActor)->Symbols.FindSymbol("A_CallSpecial", false));
auto f = dyn_cast<PFunction>(RUNTIME_CLASS(AActor)->FindSymbol("A_CallSpecial", false));
assert(f != nullptr);
return new FxVMFunctionCall(new FxSelf(sc), f, args, sc, false);
}
@ -583,7 +583,7 @@ FxVMFunctionCall *ParseAction(FScanner &sc, FState state, FString statestring, B
FName symname = FName(sc.String, true);
symname = CheckCastKludges(symname);
PFunction *afd = dyn_cast<PFunction>(bag.Info->Symbols.FindSymbol(symname, true));
PFunction *afd = dyn_cast<PFunction>(bag.Info->FindSymbol(symname, true));
if (afd != NULL)
{
FArgumentList args;

View file

@ -733,7 +733,7 @@ FieldDesc *FindField(PStruct *cls, const char * string)
VMFunction *FindVMFunction(PClass *cls, const char *name)
{
auto f = dyn_cast<PFunction>(cls->Symbols.FindSymbol(name, true));
auto f = dyn_cast<PFunction>(cls->FindSymbol(name, true));
return f == nullptr ? nullptr : f->Variants[0].Implementation;
}

View file

@ -342,7 +342,7 @@ void HandleDeprecatedFlags(AActor *defaults, PClassActor *info, bool set, int in
FName name(propname, true);
if (name != NAME_None)
{
auto propp = dyn_cast<PProperty>(info->Symbols.FindSymbol(name, true));
auto propp = dyn_cast<PProperty>(info->FindSymbol(name, true));
if (propp != nullptr)
{
*((char*)defaults + propp->Variables[0]->Offset) = set ? 1 : 0;

View file

@ -1404,7 +1404,7 @@ bool ZCCCompiler::CompileProperties(PClass *type, TArray<ZCC_Property *> &Proper
{
do
{
auto f = dyn_cast<PField>(type->Symbols.FindSymbol(id->Id, true));
auto f = dyn_cast<PField>(type->FindSymbol(id->Id, true));
if (f == nullptr)
{
Error(id, "Variable %s not found in %s", FName(id->Id).GetChars(), type->TypeName.GetChars());
@ -2113,7 +2113,7 @@ void ZCCCompiler::ProcessDefaultProperty(PClassActor *cls, ZCC_PropertyStmt *pro
FName name(propname, true);
if (name != NAME_None)
{
auto propp = dyn_cast<PProperty>(cls->Symbols.FindSymbol(name, true));
auto propp = dyn_cast<PProperty>(cls->FindSymbol(name, true));
if (propp != nullptr)
{
DispatchScriptProperty(propp, prop, (AActor *)bag.Info->Defaults, bag);

View file

@ -1,7 +1,7 @@
inline unsigned GetVirtualIndex(PClass *cls, const char *funcname)
{
// Look up the virtual function index in the defining class because this may have gotten overloaded in subclasses with something different than a virtual override.
auto sym = dyn_cast<PFunction>(cls->Symbols.FindSymbol(funcname, false));
auto sym = dyn_cast<PFunction>(cls->FindSymbol(funcname, false));
assert(sym != nullptr);
auto VIndex = sym->Variants[0].Implementation->VirtualIndex;
return VIndex;