diff --git a/src/common/engine/namedef.h b/src/common/engine/namedef.h index 144b46636..92fa6fa34 100644 --- a/src/common/engine/namedef.h +++ b/src/common/engine/namedef.h @@ -187,6 +187,8 @@ xx(Exists) xx(SetInvalid) xx(SetNull) xx(Key) +xx(Index) +xx(Find) // color channels xx(a) diff --git a/src/common/scripting/backend/codegen.cpp b/src/common/scripting/backend/codegen.cpp index ac49b3a15..09abbe604 100644 --- a/src/common/scripting/backend/codegen.cpp +++ b/src/common/scripting/backend/codegen.cpp @@ -8505,6 +8505,11 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx) } else { + if (PFunction **Override; ctx.Version >= MakeVersion(4, 11, 0) && (Override = static_cast(Self->ValueType)->FnOverrides.CheckKey(MethodName))) + { + afd_override = *Override; + } + auto elementType = static_cast(Self->ValueType)->ElementType; Self->ValueType = static_cast(Self->ValueType)->BackingType; bool isDynArrayObj = elementType->isObjectPointer(); diff --git a/src/common/scripting/core/types.cpp b/src/common/scripting/core/types.cpp index e26a60879..6830687eb 100644 --- a/src/common/scripting/core/types.cpp +++ b/src/common/scripting/core/types.cpp @@ -1985,12 +1985,114 @@ PStaticArray *NewStaticArray(PType *type) // //========================================================================== +enum OverrideFunctionRetType { + OFN_RET_VOID, + OFN_RET_VAL, + OFN_RET_KEY, + OFN_RET_BOOL, + OFN_RET_VAL_BOOL, + OFN_RET_INT, +}; +enum OverrideFunctionArgType { + OFN_ARG_VOID, + OFN_ARG_KEY, + OFN_ARG_VAL, + OFN_ARG_KEY_VAL, + OFN_ARG_ELEM, + OFN_ARG_INT_ELEM, +}; + +template +void CreateOverrideFunction(MT *self, FName name) +{ + auto Fn = Create(self->BackingType, name); + auto NativeFn = FindFunction(self->BackingType, name.GetChars()); + + assert(NativeFn); + assert(NativeFn->VMPointer); + + TArray ret; + TArray args; + TArray argflags; + TArray argnames; + + if constexpr(RetType == OFN_RET_VAL) + { + ret.Push(self->ValueType); + } + else if constexpr(RetType == OFN_RET_KEY) + { + ret.Push(self->KeyType); + } + else if constexpr(RetType == OFN_RET_BOOL) + { + ret.Push(TypeBool); + } + else if constexpr(RetType == OFN_RET_VAL_BOOL) + { + ret.Push(self->ValueType); + ret.Push(TypeBool); + } + else if constexpr(RetType == OFN_RET_INT) + { + ret.Push(TypeSInt32); + } + + args.Push(NewPointer(self->BackingType)); + argnames.Push(NAME_self); + argflags.Push(VARF_Implicit | VARF_ReadOnly); + + if constexpr(ArgType == OFN_ARG_KEY) + { + args.Push(self->KeyType); + argflags.Push(0); + argnames.Push(NAME_Key); + } + else if constexpr(ArgType == OFN_ARG_VAL) + { + + args.Push(self->ValueType); + argflags.Push(0); + argnames.Push(NAME_Value); + } + else if constexpr(ArgType == OFN_ARG_KEY_VAL) + { + args.Push(self->KeyType); + args.Push(self->ValueType); + argflags.Push(0); + argflags.Push(0); + argnames.Push(NAME_Key); + argnames.Push(NAME_Value); + } + else if constexpr(ArgType == OFN_ARG_ELEM) + { + args.Push(self->ElementType); + argflags.Push(0); + argnames.Push(NAME_Item); + } + else if constexpr(ArgType == OFN_ARG_INT_ELEM) + { + args.Push(TypeSInt32); + args.Push(self->ElementType); + argflags.Push(0); + argflags.Push(0); + argnames.Push(NAME_Index); + argnames.Push(NAME_Item); + } + + Fn->AddVariant(NewPrototype(ret, args), argflags, argnames, *NativeFn->VMPointer, VARF_Method | VARF_Native, SUF_ACTOR | SUF_OVERLAY | SUF_WEAPON | SUF_ITEM); + self->FnOverrides.Insert(name, Fn); +} + PDynArray::PDynArray(PType *etype,PStruct *backing) : ElementType(etype), BackingType(backing) { mDescriptiveName.Format("DynArray<%s>", etype->DescriptiveName()); Size = sizeof(FArray); Align = alignof(FArray); + CreateOverrideFunction (this, NAME_Find); + CreateOverrideFunction (this, NAME_Push); + CreateOverrideFunction (this, NAME_Insert); } //========================================================================== @@ -2226,96 +2328,19 @@ PDynArray *NewDynArray(PType *type) // //========================================================================== -enum OverrideFunctionRetType { - OFN_RET_VOID, - OFN_RET_VAL, - OFN_RET_KEY, - OFN_RET_BOOL, - OFN_RET_VAL_BOOL, -}; -enum OverrideFunctionArgType { - OFN_ARG_VOID, - OFN_ARG_KEY, - OFN_ARG_VAL, - OFN_ARG_KEY_VAL, -}; - -template -void CreateOverrideFunction(MT *self, FName name) -{ - auto Fn = Create(self->BackingType, name); - auto NativeFn = FindFunction(self->BackingType, name.GetChars()); - - assert(NativeFn); - assert(NativeFn->VMPointer); - - TArray ret; - TArray args; - TArray argflags; - TArray argnames; - - if constexpr(RetType == OFN_RET_VAL) - { - ret.Push(self->ValueType); - } - else if constexpr(RetType == OFN_RET_KEY) - { - ret.Push(self->KeyType); - } - else if constexpr(RetType == OFN_RET_BOOL) - { - ret.Push(TypeBool); - } - else if constexpr(RetType == OFN_RET_VAL_BOOL) - { - ret.Push(self->ValueType); - ret.Push(TypeBool); - } - - args.Push(NewPointer(self->BackingType)); - argnames.Push(NAME_self); - argflags.Push(VARF_Implicit | VARF_ReadOnly); - - if constexpr(ArgType == OFN_ARG_KEY) - { - args.Push(self->KeyType); - argflags.Push(0); - argnames.Push(NAME_Key); - } - else if constexpr(ArgType == OFN_ARG_VAL) - { - - args.Push(self->ValueType); - argflags.Push(0); - argnames.Push(NAME_Value); - } - else if constexpr(ArgType == OFN_ARG_KEY_VAL) - { - args.Push(self->KeyType); - args.Push(self->ValueType); - argflags.Push(0); - argflags.Push(0); - argnames.Push(NAME_Key); - argnames.Push(NAME_Value); - } - - Fn->AddVariant(NewPrototype(ret, args), argflags, argnames, *NativeFn->VMPointer, VARF_Method | VARF_Native,SUF_ACTOR | SUF_OVERLAY | SUF_WEAPON | SUF_ITEM); - self->FnOverrides.Insert(name, Fn); -} - PMap::PMap(PType *keytype, PType *valtype, PStruct *backing, int backing_class) : KeyType(keytype), ValueType(valtype), BackingType(backing), BackingClass((decltype(BackingClass)) backing_class) { mDescriptiveName.Format("Map<%s, %s>", keytype->DescriptiveName(), valtype->DescriptiveName()); Size = sizeof(ZSFMap); Align = alignof(ZSFMap); - CreateOverrideFunction (this, NAME_Get); - CreateOverrideFunction (this, NAME_GetIfExists); - CreateOverrideFunction (this, NAME_CheckKey); - CreateOverrideFunction (this, NAME_CheckValue); - CreateOverrideFunction (this, NAME_Insert); - CreateOverrideFunction (this, NAME_InsertNew); - CreateOverrideFunction (this, NAME_Remove); + CreateOverrideFunction< OFN_RET_VAL , OFN_ARG_KEY > (this, NAME_Get); + CreateOverrideFunction< OFN_RET_VAL , OFN_ARG_KEY > (this, NAME_GetIfExists); + CreateOverrideFunction< OFN_RET_BOOL , OFN_ARG_KEY > (this, NAME_CheckKey); + CreateOverrideFunction< OFN_RET_VAL_BOOL , OFN_ARG_KEY > (this, NAME_CheckValue); + CreateOverrideFunction< OFN_RET_VOID , OFN_ARG_KEY_VAL > (this, NAME_Insert); + CreateOverrideFunction< OFN_RET_VOID , OFN_ARG_KEY > (this, NAME_InsertNew); + CreateOverrideFunction< OFN_RET_VOID , OFN_ARG_KEY > (this, NAME_Remove); } //========================================================================== @@ -2777,9 +2802,9 @@ PMapIterator::PMapIterator(PType *keytype, PType *valtype, PStruct *backing, int mDescriptiveName.Format("MapIterator<%s, %s>", keytype->DescriptiveName(), valtype->DescriptiveName()); Size = sizeof(ZSFMap); Align = alignof(ZSFMap); - CreateOverrideFunction(this, NAME_GetKey); - CreateOverrideFunction(this, NAME_GetValue); - CreateOverrideFunction(this, NAME_SetValue); + CreateOverrideFunction(this, NAME_GetKey); + CreateOverrideFunction(this, NAME_GetValue); + CreateOverrideFunction(this, NAME_SetValue); } //========================================================================== diff --git a/src/common/scripting/core/types.h b/src/common/scripting/core/types.h index f4ac3447d..789cc7d3e 100644 --- a/src/common/scripting/core/types.h +++ b/src/common/scripting/core/types.h @@ -512,6 +512,8 @@ public: PType *ElementType; PStruct *BackingType; + TMap FnOverrides; + bool IsMatch(intptr_t id1, intptr_t id2) const override; void GetTypeIDs(intptr_t &id1, intptr_t &id2) const override;