diff --git a/src/common/engine/namedef.h b/src/common/engine/namedef.h index 41572fade..8be149bea 100644 --- a/src/common/engine/namedef.h +++ b/src/common/engine/namedef.h @@ -305,6 +305,7 @@ xx(BuiltinNew) xx(GetClass) xx(GetParentClass) xx(GetClassName) +xx(IsAbstract) xx(GetDefaultByType) xx(Exp) xx(Log10) diff --git a/src/common/scripting/backend/codegen.cpp b/src/common/scripting/backend/codegen.cpp index f28da4cb0..f6f52f0bc 100644 --- a/src/common/scripting/backend/codegen.cpp +++ b/src/common/scripting/backend/codegen.cpp @@ -8256,6 +8256,14 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx) return x->Resolve(ctx); } } + if (MethodName == NAME_IsAbstract && Self->ValueType->isClassPointer()) + { + if (CheckArgSize(NAME_IsAbstract, ArgList, 0, 0, ScriptPosition)) + { + auto x = new FxIsAbstract(Self); + return x->Resolve(ctx); + } + } if (Self->ValueType->isRealPointer()) { @@ -9252,6 +9260,47 @@ ExpEmit FxGetClassName::Emit(VMFunctionBuilder *build) // //========================================================================== +FxIsAbstract::FxIsAbstract(FxExpression *self) + :FxExpression(EFX_IsAbstract, self->ScriptPosition) +{ + Self = self; +} + +FxIsAbstract::~FxIsAbstract() +{ + SAFE_DELETE(Self); +} + +FxExpression *FxIsAbstract::Resolve(FCompileContext &ctx) +{ + SAFE_RESOLVE(Self, ctx); + + if (!Self->ValueType->isClassPointer()) + { + ScriptPosition.Message(MSG_ERROR, "IsAbstract() requires a class pointer"); + delete this; + return nullptr; + } + ValueType = TypeBool; + return this; +} + +ExpEmit FxIsAbstract::Emit(VMFunctionBuilder *build) +{ + ExpEmit op = Self->Emit(build); + op.Free(build); + + ExpEmit to(build, REGT_INT); + build->Emit(OP_LBU, to.RegNum, op.RegNum, build->GetConstantInt(myoffsetof(PClass, bAbstract))); + + return to; +} + +//========================================================================== +// +// +//========================================================================== + FxColorLiteral::FxColorLiteral(FArgumentList &args, FScriptPosition &sc) :FxExpression(EFX_ColorLiteral, sc) { diff --git a/src/common/scripting/backend/codegen.h b/src/common/scripting/backend/codegen.h index 59037929c..ac5f058ab 100644 --- a/src/common/scripting/backend/codegen.h +++ b/src/common/scripting/backend/codegen.h @@ -298,6 +298,7 @@ enum EFxType EFX_GetClass, EFX_GetParentClass, EFX_GetClassName, + EFX_IsAbstract, EFX_StrLen, EFX_ColorLiteral, EFX_GetDefaultByType, @@ -1663,6 +1664,24 @@ public: ExpEmit Emit(VMFunctionBuilder *build); }; +//========================================================================== +// +// FxIsAbstract +// +//========================================================================== + +class FxIsAbstract : public FxExpression +{ + FxExpression* Self; + +public: + + FxIsAbstract(FxExpression* self); + ~FxIsAbstract(); + FxExpression *Resolve(FCompileContext&); + ExpEmit Emit(VMFunctionBuilder* build); +}; + //========================================================================== // // FxColorLiteral