From c4ced578e28a8b3c1ef27c18fd2889373e2b5694 Mon Sep 17 00:00:00 2001 From: IllidanS4 Date: Fri, 19 Apr 2019 14:20:39 +0200 Subject: [PATCH] var_addr and co. --- pawno/include/PawnPlus.inc | 37 ++++++++++++++++++++---- plugins/src/hooks.cpp | 35 +++++++++++++++------- plugins/src/natives/str.cpp | 19 +++++++++++- plugins/src/natives/variant.cpp | 43 +++++++++++++++++++++++++++ plugins/src/objects/object_pool.h | 48 ++++++++++--------------------- 5 files changed, 132 insertions(+), 50 deletions(-) diff --git a/pawno/include/PawnPlus.inc b/pawno/include/PawnPlus.inc index 2950a50..bfc8591 100644 --- a/pawno/include/PawnPlus.inc +++ b/pawno/include/PawnPlus.inc @@ -448,7 +448,7 @@ native String:str_new_arr(const arr[], size=sizeof(arr), str_create_mode:mode=st native String:str_new_static(const str[], str_create_mode:mode=str_preserve, size=sizeof(str)); native String:str_new_buf(size); native AmxString:str_addr(StringTag:str); -native ConstAmxString:str_addr_const(ConstStringTag:str) = str_addr; +native ConstAmxString:str_addr_const(ConstStringTag:str); native AmxStringBuffer:str_buf_addr(StringTag:str); native String:str_acquire(StringTag:str); native String:str_release(StringTag:str); @@ -559,6 +559,9 @@ native Variant:var_new_buf(size, TagTag:tag_id=0); native Variant:var_new_str(const value[]); native Variant:var_new_str_s(ConstStringTag:value); native Variant:var_new_var(ConstVariantTag:value); +native AmxVariant:var_addr(VariantTag:var); +native ConstAmxVariant:var_addr_const(ConstVariantTag:var); +native AmxVariantBuffer:var_buf_addr(VariantTag:str); native Variant:var_acquire(VariantTag:var); native Variant:var_release(VariantTag:var); native var_delete(VariantTag:var); @@ -1673,6 +1676,9 @@ PP_PROHIBIT_UNARY_OPERATORS(ConstString); PP_PROHIBIT_UNARY_OPERATORS(AmxString); PP_PROHIBIT_UNARY_OPERATORS(ConstAmxString); PP_PROHIBIT_UNARY_OPERATORS(AmxStringBuffer); +PP_PROHIBIT_UNARY_OPERATORS(AmxVariant); +PP_PROHIBIT_UNARY_OPERATORS(ConstAmxVariant); +PP_PROHIBIT_UNARY_OPERATORS(AmxVariantBuffer); forward String:operator=(AmxString:arg); forward ConstString:operator=(AmxString:arg); @@ -1680,6 +1686,12 @@ forward String:operator=(ConstAmxString:arg); forward ConstString:operator=(ConstAmxString:arg); forward String:operator=(AmxStringBuffer:arg); forward ConstString:operator=(AmxStringBuffer:arg); +forward Variant:operator=(AmxVariant:arg); +forward ConstVariant:operator=(AmxVariant:arg); +forward Variant:operator=(ConstAmxVariant:arg); +forward ConstVariant:operator=(ConstAmxVariant:arg); +forward Variant:operator=(AmxVariantBuffer:arg); +forward ConstVariant:operator=(AmxVariantBuffer:arg); #undef PP_PROHIBIT_UNARY_OPERATORS @@ -1697,28 +1709,43 @@ forward ConstString:operator=(AmxStringBuffer:arg); PP_PROHIBIT_BINARY_OPEARTORS(%0,ConstString); \ PP_PROHIBIT_BINARY_OPEARTORS(%0,AmxString); \ PP_PROHIBIT_BINARY_OPEARTORS(%0,ConstAmxString); \ - PP_PROHIBIT_BINARY_OPEARTORS(%0,AmxStringBuffer) + PP_PROHIBIT_BINARY_OPEARTORS(%0,AmxStringBuffer); \ + PP_PROHIBIT_BINARY_OPEARTORS(%0,AmxVariant); \ + PP_PROHIBIT_BINARY_OPEARTORS(%0,ConstAmxVariant); \ + PP_PROHIBIT_BINARY_OPEARTORS(%0,AmxVariantBuffer) PP_PROHIBIT_BINARY_OPEARTORS2(String); PP_PROHIBIT_BINARY_OPEARTORS2(ConstString); PP_PROHIBIT_BINARY_OPEARTORS2(AmxString); PP_PROHIBIT_BINARY_OPEARTORS2(ConstAmxString); PP_PROHIBIT_BINARY_OPEARTORS2(AmxStringBuffer); +PP_PROHIBIT_BINARY_OPEARTORS2(AmxVariant); +PP_PROHIBIT_BINARY_OPEARTORS2(ConstAmxVariant); +PP_PROHIBIT_BINARY_OPEARTORS2(AmxVariantBuffer); #undef PP_PROHIBIT_BINARY_OPEARTORS stock ConstString:operator=(String:arg) return ConstString:arg; forward String:operator=(ConstString:arg); + native AmxString:operator=(String:arg) = str_addr; -native ConstAmxString:operator=(String:arg) = str_addr; -native ConstAmxString:operator=(ConstString:arg) = str_addr; +native ConstAmxString:operator=(String:arg) = str_addr_const; +native ConstAmxString:operator=(ConstString:arg) = str_addr_const; stock ConstAmxString:operator=(AmxString:arg) return ConstAmxString:arg; forward AmxString:operator=(ConstString:arg); forward AmxString:operator=(ConstAmxString:arg); native AmxStringBuffer:operator=(String:arg) = str_buf_addr; - stock AmxStringBuffer:operator+(AmxStringBuffer:arg1, arg2) return AmxStringBuffer:(_:arg1+arg2); +native AmxVariant:operator=(Variant:arg) = var_addr; +native ConstAmxVariant:operator=(Variant:arg) = var_addr_const; +native ConstAmxVariant:operator=(ConstVariant:arg) = var_addr_const; +stock ConstAmxVariant:operator=(AmxVariant:arg) return ConstAmxVariant:arg; +forward AmxVariant:operator=(ConstVariant:arg); +forward AmxVariant:operator=(ConstAmxVariant:arg); +native AmxVariantBuffer:operator=(Variant:arg) = var_buf_addr; +stock AmxVariantBuffer:operator+(AmxVariantBuffer:arg1, arg2) return AmxVariantBuffer:(_:arg1+arg2); + native String:operator+(String:arg1, String:arg2) = str_cat; native String:operator+(String:arg1, ConstString:arg2) = str_cat; native String:operator+(ConstString:arg1, String:arg2) = str_cat; diff --git a/plugins/src/hooks.cpp b/plugins/src/hooks.cpp index 56b04bb..034ece5 100644 --- a/plugins/src/hooks.cpp +++ b/plugins/src/hooks.cpp @@ -3,6 +3,7 @@ #include "exec.h" #include "amxinfo.h" #include "modules/strings.h" +#include "modules/variants.h" #include "modules/events.h" #include "modules/capi.h" #include "modules/debug.h" @@ -142,11 +143,17 @@ namespace Hooks *phys_addr = strings::null_value1; return AMX_ERR_NONE; } - auto &ptr = strings::pool.get(amx, amx_addr); - if(ptr != nullptr) + decltype(strings::pool)::ref_container *str; + if(strings::pool.get_by_addr(amx, amx_addr, str)) { - strings::pool.set_cache(ptr); - *phys_addr = &(*ptr)[0]; + strings::pool.set_cache(*str); + *phys_addr = &(**str)[0]; + return AMX_ERR_NONE; + } + decltype(variants::pool)::ref_container *var; + if(variants::pool.get_by_addr(amx, amx_addr, var)) + { + *phys_addr = &(**var)[0]; return AMX_ERR_NONE; } }else if(ret == 0 && hook_ref_args) @@ -162,11 +169,17 @@ namespace Hooks *phys_addr = strings::null_value2; return AMX_ERR_NONE; } - auto &ptr = strings::pool.get(amx, **phys_addr); - if(ptr != nullptr) + decltype(strings::pool)::ref_container *str; + if(strings::pool.get_by_addr(amx, amx_addr, str)) + { + strings::pool.set_cache(*str); + *phys_addr = &(**str)[0]; + return AMX_ERR_NONE; + } + decltype(variants::pool)::ref_container *var; + if(variants::pool.get_by_addr(amx, amx_addr, var)) { - strings::pool.set_cache(ptr); - *phys_addr = &(*ptr)[0]; + *phys_addr = &(**var)[0]; return AMX_ERR_NONE; } } @@ -175,10 +188,10 @@ namespace Hooks int AMX_HOOK_FUNC(amx_StrLen, const cell *cstring, int *length) { - auto &str = strings::pool.find_cache(cstring); - if(str != nullptr) + const decltype(strings::pool)::ref_container *str; + if(strings::pool.find_cache(cstring, str)) { - *length = str->size(); + *length = (*str)->size(); return AMX_ERR_NONE; } diff --git a/plugins/src/natives/str.cpp b/plugins/src/natives/str.cpp index ed70bc3..58b3dc0 100644 --- a/plugins/src/natives/str.cpp +++ b/plugins/src/natives/str.cpp @@ -95,6 +95,22 @@ namespace Natives { decltype(strings::pool)::ref_container *str; if(!strings::pool.get_by_id(params[1], str) && str != nullptr) amx_LogicError(errors::pointer_invalid, "string", params[1]); + if(str == nullptr) + { + return strings::pool.get_null_address(amx); + } + return strings::pool.get_address(amx, *str); + } + + // native ConstAmxString:str_addr_const(ConstStringTag:str); + AMX_DEFINE_NATIVE(str_addr_const, 1) + { + decltype(strings::pool)::ref_container *str; + if(!strings::pool.get_by_id(params[1], str) && str != nullptr) amx_LogicError(errors::pointer_invalid, "string", params[1]); + if(str == nullptr) + { + return strings::pool.get_null_address(amx); + } return strings::pool.get_address(amx, *str); } @@ -102,7 +118,7 @@ namespace Natives AMX_DEFINE_NATIVE(str_buf_addr, 1) { decltype(strings::pool)::ref_container *str; - if(!strings::pool.get_by_id(params[1], str) && str != nullptr) amx_LogicError(errors::pointer_invalid, "string", params[1]); + if(!strings::pool.get_by_id(params[1], str)) amx_LogicError(errors::pointer_invalid, "string", params[1]); return strings::pool.get_inner_address(amx, *str); } @@ -1120,6 +1136,7 @@ static AMX_NATIVE_INFO native_list[] = AMX_DECLARE_NATIVE(str_new_static), AMX_DECLARE_NATIVE(str_new_buf), AMX_DECLARE_NATIVE(str_addr), + AMX_DECLARE_NATIVE(str_addr_const), AMX_DECLARE_NATIVE(str_buf_addr), AMX_DECLARE_NATIVE(str_acquire), AMX_DECLARE_NATIVE(str_release), diff --git a/plugins/src/natives/variant.cpp b/plugins/src/natives/variant.cpp index f514afc..878ba30 100644 --- a/plugins/src/natives/variant.cpp +++ b/plugins/src/natives/variant.cpp @@ -75,6 +75,46 @@ namespace Natives return value_at<1>::var_new(amx, params); } + // native AmxVariant:var_addr(VariantTag:str); + AMX_DEFINE_NATIVE(var_addr, 1) + { + decltype(variants::pool)::ref_container *var; + if(!variants::pool.get_by_id(params[1], var) && var != nullptr) amx_LogicError(errors::pointer_invalid, "variant", params[1]); + if(var == nullptr) + { + return variants::pool.get_null_address(amx); + } + if((*var)->is_cell()) + { + amx_LogicError(errors::operation_not_supported, "variant"); + } + return variants::pool.get_address(amx, *var); + } + + // native ConstAmxVariant:var_addr_const(ConstVariantTag:str); + AMX_DEFINE_NATIVE(var_addr_const, 1) + { + decltype(variants::pool)::ref_container *var; + if(!variants::pool.get_by_id(params[1], var) && var != nullptr) amx_LogicError(errors::pointer_invalid, "variant", params[1]); + if(var == nullptr) + { + return variants::pool.get_null_address(amx); + } + return variants::pool.get_address(amx, *var); + } + + // native AmxVariantBuffer:var_buf_addr(VariantTag:str); + AMX_DEFINE_NATIVE(var_buf_addr, 1) + { + decltype(variants::pool)::ref_container *var; + if(!variants::pool.get_by_id(params[1], var)) amx_LogicError(errors::pointer_invalid, "variant", params[1]); + if((*var)->is_cell()) + { + amx_LogicError(errors::operation_not_supported, "variant"); + } + return variants::pool.get_inner_address(amx, *var); + } + // native Variant:var_acquire(VariantTag:var); AMX_DEFINE_NATIVE(var_acquire, 1) { @@ -545,6 +585,9 @@ static AMX_NATIVE_INFO native_list[] = AMX_DECLARE_NATIVE(var_new_str), AMX_DECLARE_NATIVE(var_new_str_s), AMX_DECLARE_NATIVE(var_new_var), + AMX_DECLARE_NATIVE(var_addr), + AMX_DECLARE_NATIVE(var_addr_const), + AMX_DECLARE_NATIVE(var_buf_addr), AMX_DECLARE_NATIVE(var_acquire), AMX_DECLARE_NATIVE(var_release), AMX_DECLARE_NATIVE(var_delete), diff --git a/plugins/src/objects/object_pool.h b/plugins/src/objects/object_pool.h index b14b59a..d1e76d9 100644 --- a/plugins/src/objects/object_pool.h +++ b/plugins/src/objects/object_pool.h @@ -217,27 +217,7 @@ class object_pool } }; - class ref_container_virtual_null : public ref_container_virtual - { - public: - ref_container_virtual_null(std::nullptr_t) : ref_container_virtual(nullptr) - { - - } - - virtual ObjType *get() override - { - return nullptr; - } - - virtual const ObjType *get() const override - { - return nullptr; - } - }; - typedef typename std::conditional::value, ref_container_virtual, ref_container_simple>::type ref_container; - typedef typename std::conditional::value, ref_container_virtual_null, ref_container>::type ref_container_null; typedef ref_container &object_ptr; typedef const ref_container &const_object_ptr; @@ -245,11 +225,6 @@ class object_pool typedef decltype(&static_cast(nullptr)->operator[](0)) const_inner_ptr; typedef aux::shared_id_set_pool list_type; - static ref_container_null &null_ref() - { - static ref_container_null obj = nullptr; - return obj; - } private: list_type global_object_list; @@ -306,6 +281,12 @@ class object_pool return reinterpret_cast(&obj->operator[](0)) - reinterpret_cast(data); } + cell get_null_address(AMX *amx) const + { + unsigned char *data = amx_GetData(amx); + return -reinterpret_cast(data); + } + bool is_null_address(AMX *amx, cell addr) const { if(addr >= 0 && addr < amx->stp) @@ -358,14 +339,15 @@ class object_pool inner_cache[&obj->operator[](0)] = &obj; } - object_ptr find_cache(const_inner_ptr ptr) + bool find_cache(const_inner_ptr ptr, const ref_container *&obj) { auto it = inner_cache.find(ptr); if(it != inner_cache.end()) { - return const_cast(*it->second); + obj = it->second; + return true; } - return null_ref(); + return false; } bool remove(object_ptr obj) @@ -496,21 +478,21 @@ class object_pool return {}; } - object_ptr get(AMX *amx, cell addr) + bool get_by_addr(AMX *amx, cell addr, ref_container *&obj) { - auto obj = reinterpret_cast(amx_GetData(amx) + addr); + obj = reinterpret_cast(amx_GetData(amx) + addr); auto it = local_object_list.find(obj); if(it != local_object_list.end()) { - return *it->second; + return true; } it = global_object_list.find(obj); if(it != global_object_list.end()) { - return *it->second; + return true; } - return null_ref(); + return false; } size_t local_size() const