Skip to content

Commit

Permalink
var_addr and co.
Browse files Browse the repository at this point in the history
  • Loading branch information
IS4Code committed Apr 19, 2019
1 parent 9f9b5f5 commit c4ced57
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 50 deletions.
37 changes: 32 additions & 5 deletions pawno/include/PawnPlus.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -1673,13 +1676,22 @@ 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);
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

Expand All @@ -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;
Expand Down
35 changes: 24 additions & 11 deletions plugins/src/hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
Expand All @@ -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;
}
}
Expand All @@ -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;
}

Expand Down
19 changes: 18 additions & 1 deletion plugins/src/natives/str.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,30 @@ 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);
}

// native AmxStringBuffer:str_buf_addr(StringTag:str);
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);
}

Expand Down Expand Up @@ -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),
Expand Down
43 changes: 43 additions & 0 deletions plugins/src/natives/variant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,46 @@ namespace Natives
return value_at<1>::var_new<dyn_func_var>(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)
{
Expand Down Expand Up @@ -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),
Expand Down
48 changes: 15 additions & 33 deletions plugins/src/objects/object_pool.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,39 +217,14 @@ 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<std::has_virtual_destructor<ObjType>::value, ref_container_virtual, ref_container_simple>::type ref_container;
typedef typename std::conditional<std::has_virtual_destructor<ObjType>::value, ref_container_virtual_null, ref_container>::type ref_container_null;

typedef ref_container &object_ptr;
typedef const ref_container &const_object_ptr;
typedef decltype(&static_cast<ObjType*>(nullptr)->operator[](0)) inner_ptr;
typedef decltype(&static_cast<const ObjType*>(nullptr)->operator[](0)) const_inner_ptr;

typedef aux::shared_id_set_pool<ref_container> list_type;
static ref_container_null &null_ref()
{
static ref_container_null obj = nullptr;
return obj;
}

private:
list_type global_object_list;
Expand Down Expand Up @@ -306,6 +281,12 @@ class object_pool
return reinterpret_cast<cell>(&obj->operator[](0)) - reinterpret_cast<cell>(data);
}

cell get_null_address(AMX *amx) const
{
unsigned char *data = amx_GetData(amx);
return -reinterpret_cast<cell>(data);
}

bool is_null_address(AMX *amx, cell addr) const
{
if(addr >= 0 && addr < amx->stp)
Expand Down Expand Up @@ -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<object_ptr>(*it->second);
obj = it->second;
return true;
}
return null_ref();
return false;
}

bool remove(object_ptr obj)
Expand Down Expand Up @@ -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<ref_container*>(amx_GetData(amx) + addr);
obj = reinterpret_cast<ref_container*>(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
Expand Down

0 comments on commit c4ced57

Please sign in to comment.