- separated the code generation from the DECORATE parser and cleaned up the interface to the code generator. Most importantly, the VMScriptFunctions are now preallocated when being added to the list of functions to compile and will be filled in later by the code generator. This allowed the removal of some ugly maintenance code.

This commit is contained in:
Christoph Oelckers 2016-10-13 00:53:59 +02:00
commit a72fbb771f
16 changed files with 276 additions and 263 deletions

View file

@ -41,6 +41,9 @@
*/
#include "m_random.h"
#include "sc_man.h"
#include "s_sound.h"
#include "actor.h"
#define CHECKRESOLVED() if (isresolved) return this; isresolved=true;
@ -58,14 +61,15 @@ class FxJumpStatement;
//
//
//==========================================================================
struct FScriptPosition;
struct FCompileContext
{
TArray<FxJumpStatement *> Jumps;
PPrototype *ReturnProto;
PClassActor *Class;
PClass *Class;
FCompileContext(PClassActor *cls = nullptr, PPrototype *ret = nullptr);
FCompileContext(PClass *cls = nullptr, PPrototype *ret = nullptr);
PSymbol *FindInClass(FName identifier);
PSymbol *FindGlobal(FName identifier);
@ -1175,7 +1179,6 @@ public:
class FxDamageValue : public FxExpression
{
FxExpression *val;
VMScriptFunction *MyFunction;
public:
@ -1184,8 +1187,6 @@ public:
FxExpression *Resolve(FCompileContext&);
ExpEmit Emit(VMFunctionBuilder *build);
VMScriptFunction *GetFunction() const { return MyFunction; }
void SetFunction(VMScriptFunction *func) { MyFunction = func; }
};
//==========================================================================

View file

@ -91,7 +91,7 @@ static const FLOP FxFlops[] =
//
//==========================================================================
FCompileContext::FCompileContext(PClassActor *cls, PPrototype *ret) : Class(cls), ReturnProto(ret)
FCompileContext::FCompileContext(PClass *cls, PPrototype *ret) : Class(cls), ReturnProto(ret)
{
}
@ -3902,7 +3902,7 @@ VMFunction *FxVMFunctionCall::GetDirectFunction()
// then it can be a "direct" function. That is, the DECORATE
// definition can call that function directly without wrapping
// it inside VM code.
if (EmitTail && (ArgList ? ArgList->Size() : 0) == 0 && (Function->Flags & VARF_Action))
if ((ArgList ? ArgList->Size() : 0) == 0 && (Function->Flags & VARF_Action))
{
return Function->Variants[0].Implementation;
}
@ -4922,20 +4922,19 @@ FxExpression *FxStateByIndex::Resolve(FCompileContext &ctx)
{
CHECKRESOLVED();
ABORT(ctx.Class);
auto aclass = dyn_cast<PClassActor>(ctx.Class);
if (ctx.Class->NumOwnedStates == 0)
{
// This can't really happen
assert(false);
}
if (ctx.Class->NumOwnedStates <= index)
// This expression type can only be used from DECORATE, so there's no need to consider the possibility of calling it from a non-actor.
assert(aclass != nullptr && aclass->NumOwnedStates > 0);
if (aclass->NumOwnedStates <= index)
{
ScriptPosition.Message(MSG_ERROR, "%s: Attempt to jump to non existing state index %d",
ctx.Class->TypeName.GetChars(), index);
delete this;
return NULL;
}
FxExpression *x = new FxConstant(ctx.Class->OwnedStates + index, ScriptPosition);
FxExpression *x = new FxConstant(aclass->OwnedStates + index, ScriptPosition);
delete this;
return x;
}
@ -5245,7 +5244,6 @@ FxDamageValue::FxDamageValue(FxExpression *v)
{
val = v;
ValueType = TypeVoid;
MyFunction = NULL;
}
FxDamageValue::~FxDamageValue()