diff options
Diffstat (limited to 'core/variant/variant_call.cpp')
-rw-r--r-- | core/variant/variant_call.cpp | 345 |
1 files changed, 304 insertions, 41 deletions
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index 8f2d252810..61f3f7d82e 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -34,6 +34,7 @@ #include "core/crypto/crypto_core.h" #include "core/debugger/engine_debugger.h" #include "core/io/compression.h" +#include "core/io/marshalls.h" #include "core/object/class_db.h" #include "core/os/os.h" #include "core/templates/local_vector.h" @@ -73,6 +74,16 @@ static _FORCE_INLINE_ void vc_method_call(void (T::*method)(P...) const, Variant } template <class R, class T, class... P> +static _FORCE_INLINE_ void vc_method_call_static(R (*method)(T *, P...), Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { + call_with_variant_args_retc_static_helper_dv(VariantGetInternalPtr<T>::get_ptr(base), method, p_args, p_argcount, r_ret, p_defvals, r_error); +} + +template <class T, class... P> +static _FORCE_INLINE_ void vc_method_call_static(void (*method)(T *, P...), Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { + call_with_variant_args_static_helper_dv(VariantGetInternalPtr<T>::get_ptr(base), method, p_args, p_argcount, p_defvals, r_error); +} + +template <class R, class T, class... P> static _FORCE_INLINE_ void vc_validated_call(R (T::*method)(P...), Variant *base, const Variant **p_args, Variant *r_ret) { call_with_validated_variant_args_ret(base, method, p_args, r_ret); } @@ -91,6 +102,16 @@ static _FORCE_INLINE_ void vc_validated_call(void (T::*method)(P...) const, Vari call_with_validated_variant_argsc(base, method, p_args); } +template <class R, class T, class... P> +static _FORCE_INLINE_ void vc_validated_call_static(R (*method)(T *, P...), Variant *base, const Variant **p_args, Variant *r_ret) { + call_with_validated_variant_args_static_retc(base, method, p_args, r_ret); +} + +template <class T, class... P> +static _FORCE_INLINE_ void vc_validated_call_static(void (*method)(T *, P...), Variant *base, const Variant **p_args, Variant *r_ret) { + call_with_validated_variant_args_static(base, method, p_args); +} + template <class R, class... P> static _FORCE_INLINE_ void vc_validated_static_call(R (*method)(P...), const Variant **p_args, Variant *r_ret) { call_with_validated_variant_args_static_method_ret(method, p_args, r_ret); @@ -146,6 +167,11 @@ static _FORCE_INLINE_ void vc_change_return_type(R (*method)(P...), Variant *v) VariantTypeAdjust<R>::adjust(v); } +template <class... P> +static _FORCE_INLINE_ void vc_change_return_type(void (*method)(P...), Variant *v) { + VariantInternal::clear(v); +} + template <class R, class T, class... P> static _FORCE_INLINE_ int vc_get_argument_count(R (T::*method)(P...)) { return sizeof...(P); @@ -229,6 +255,11 @@ static _FORCE_INLINE_ Variant::Type vc_get_return_type(R (*method)(P...)) { return GetTypeInfo<R>::VARIANT_TYPE; } +template <class... P> +static _FORCE_INLINE_ Variant::Type vc_get_return_type(void (*method)(P...)) { + return Variant::NIL; +} + template <class R, class T, class... P> static _FORCE_INLINE_ bool vc_has_return_type(R (T::*method)(P...)) { return true; @@ -393,45 +424,50 @@ static _FORCE_INLINE_ void vc_ptrcall(R (*method)(T *, P...), void *p_base, cons call_with_ptr_args_static_retc<T, R, P...>(reinterpret_cast<T *>(p_base), method, p_args, r_ret); } -#define FUNCTION_CLASS(m_class, m_method_name, m_method_ptr) \ - struct Method_##m_class##_##m_method_name { \ - static void call(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { \ - call_with_variant_args_retc_static_helper_dv(VariantGetInternalPtr<m_class>::get_ptr(base), m_method_ptr, p_args, p_argcount, r_ret, p_defvals, r_error); \ - } \ - static void validated_call(Variant *base, const Variant **p_args, int p_argcount, Variant *r_ret) { \ - vc_change_return_type(m_method_ptr, r_ret); \ - call_with_validated_variant_args_static_retc(base, m_method_ptr, p_args, r_ret); \ - } \ - static void ptrcall(void *p_base, const void **p_args, void *r_ret, int p_argcount) { \ - vc_ptrcall(m_method_ptr, p_base, p_args, r_ret); \ - } \ - static int get_argument_count() { \ - return vc_get_argument_count(m_method_ptr); \ - } \ - static Variant::Type get_argument_type(int p_arg) { \ - return vc_get_argument_type(m_method_ptr, p_arg); \ - } \ - static Variant::Type get_return_type() { \ - return vc_get_return_type(m_method_ptr); \ - } \ - static bool has_return_type() { \ - return true; \ - } \ - static bool is_const() { \ - return true; \ - } \ - static bool is_static() { \ - return false; \ - } \ - static bool is_vararg() { \ - return false; \ - } \ - static Variant::Type get_base_type() { \ - return GetTypeInfo<m_class>::VARIANT_TYPE; \ - } \ - static StringName get_name() { \ - return #m_method_name; \ - } \ +template <class T, class... P> +static _FORCE_INLINE_ void vc_ptrcall(void (*method)(T *, P...), void *p_base, const void **p_args, void *r_ret) { + call_with_ptr_args_static<T, P...>(reinterpret_cast<T *>(p_base), method, p_args); +} + +#define FUNCTION_CLASS(m_class, m_method_name, m_method_ptr, m_const) \ + struct Method_##m_class##_##m_method_name { \ + static void call(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { \ + vc_method_call_static(m_method_ptr, base, p_args, p_argcount, r_ret, p_defvals, r_error); \ + } \ + static void validated_call(Variant *base, const Variant **p_args, int p_argcount, Variant *r_ret) { \ + vc_change_return_type(m_method_ptr, r_ret); \ + vc_validated_call_static(m_method_ptr, base, p_args, r_ret); \ + } \ + static void ptrcall(void *p_base, const void **p_args, void *r_ret, int p_argcount) { \ + vc_ptrcall(m_method_ptr, p_base, p_args, r_ret); \ + } \ + static int get_argument_count() { \ + return vc_get_argument_count(m_method_ptr); \ + } \ + static Variant::Type get_argument_type(int p_arg) { \ + return vc_get_argument_type(m_method_ptr, p_arg); \ + } \ + static Variant::Type get_return_type() { \ + return vc_get_return_type(m_method_ptr); \ + } \ + static bool has_return_type() { \ + return vc_has_return_type_static(m_method_ptr); \ + } \ + static bool is_const() { \ + return m_const; \ + } \ + static bool is_static() { \ + return false; \ + } \ + static bool is_vararg() { \ + return false; \ + } \ + static Variant::Type get_base_type() { \ + return GetTypeInfo<m_class>::VARIANT_TYPE; \ + } \ + static StringName get_name() { \ + return #m_method_name; \ + } \ }; #define VARARG_CLASS(m_class, m_method_name, m_method_ptr, m_has_return, m_return_type) \ @@ -590,6 +626,195 @@ struct _VariantCall { return s; } + static int64_t func_PackedByteArray_decode_u8(PackedByteArray *p_instance, int64_t p_offset) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND_V(p_offset < 0 || p_offset > int64_t(size) - 1, 0); + const uint8_t *r = p_instance->ptr(); + return r[p_offset]; + } + static int64_t func_PackedByteArray_decode_s8(PackedByteArray *p_instance, int64_t p_offset) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND_V(p_offset < 0 || p_offset > int64_t(size) - 1, 0); + const uint8_t *r = p_instance->ptr(); + return *((const int8_t *)&r[p_offset]); + } + static int64_t func_PackedByteArray_decode_u16(PackedByteArray *p_instance, int64_t p_offset) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND_V(p_offset < 0 || p_offset > (int64_t(size) - 2), 0); + const uint8_t *r = p_instance->ptr(); + return decode_uint16(&r[p_offset]); + } + static int64_t func_PackedByteArray_decode_s16(PackedByteArray *p_instance, int64_t p_offset) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND_V(p_offset < 0 || p_offset > (int64_t(size) - 2), 0); + const uint8_t *r = p_instance->ptr(); + return (int16_t)decode_uint16(&r[p_offset]); + } + static int64_t func_PackedByteArray_decode_u32(PackedByteArray *p_instance, int64_t p_offset) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND_V(p_offset < 0 || p_offset > (int64_t(size) - 4), 0); + const uint8_t *r = p_instance->ptr(); + return decode_uint32(&r[p_offset]); + } + static int64_t func_PackedByteArray_decode_s32(PackedByteArray *p_instance, int64_t p_offset) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND_V(p_offset < 0 || p_offset > (int64_t(size) - 4), 0); + const uint8_t *r = p_instance->ptr(); + return (int32_t)decode_uint32(&r[p_offset]); + } + static int64_t func_PackedByteArray_decode_u64(PackedByteArray *p_instance, int64_t p_offset) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND_V(p_offset < 0 || p_offset > (int64_t(size) - 8), 0); + const uint8_t *r = p_instance->ptr(); + return (int64_t)decode_uint64(&r[p_offset]); + } + static int64_t func_PackedByteArray_decode_s64(PackedByteArray *p_instance, int64_t p_offset) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND_V(p_offset < 0 || p_offset > (int64_t(size) - 8), 0); + const uint8_t *r = p_instance->ptr(); + return (int64_t)decode_uint64(&r[p_offset]); + } + static double func_PackedByteArray_decode_half(PackedByteArray *p_instance, int64_t p_offset) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND_V(p_offset < 0 || p_offset > (int64_t(size) - 2), 0); + const uint8_t *r = p_instance->ptr(); + return Math::half_to_float(decode_uint16(&r[p_offset])); + } + static double func_PackedByteArray_decode_float(PackedByteArray *p_instance, int64_t p_offset) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND_V(p_offset < 0 || p_offset > (int64_t(size) - 4), 0); + const uint8_t *r = p_instance->ptr(); + return decode_float(&r[p_offset]); + } + + static double func_PackedByteArray_decode_double(PackedByteArray *p_instance, int64_t p_offset) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND_V(p_offset < 0 || p_offset > (int64_t(size) - 8), 0); + const uint8_t *r = p_instance->ptr(); + return decode_double(&r[p_offset]); + } + + static bool func_PackedByteArray_has_encoded_var(PackedByteArray *p_instance, int64_t p_offset, bool p_allow_objects) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND_V(p_offset < 0, false); + const uint8_t *r = p_instance->ptr(); + Variant ret; + Error err = decode_variant(ret, r + p_offset, size - p_offset, nullptr, p_allow_objects); + return err == OK; + } + + static Variant func_PackedByteArray_decode_var(PackedByteArray *p_instance, int64_t p_offset, bool p_allow_objects) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND_V(p_offset < 0, Variant()); + const uint8_t *r = p_instance->ptr(); + Variant ret; + Error err = decode_variant(ret, r + p_offset, size - p_offset, nullptr, p_allow_objects); + if (err != OK) { + ret = Variant(); + } + return ret; + } + + static int64_t func_PackedByteArray_decode_var_size(PackedByteArray *p_instance, int64_t p_offset, bool p_allow_objects) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND_V(p_offset < 0, 0); + const uint8_t *r = p_instance->ptr(); + Variant ret; + int r_size; + Error err = decode_variant(ret, r + p_offset, size - p_offset, &r_size, p_allow_objects); + if (err == OK) { + return r_size; + } + return 0; + } + + static void func_PackedByteArray_encode_u8(PackedByteArray *p_instance, int64_t p_offset, int64_t p_value) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 1); + uint8_t *w = p_instance->ptrw(); + *((uint8_t *)&w[p_offset]) = p_value; + } + static void func_PackedByteArray_encode_s8(PackedByteArray *p_instance, int64_t p_offset, int64_t p_value) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 1); + uint8_t *w = p_instance->ptrw(); + *((int8_t *)&w[p_offset]) = p_value; + } + + static void func_PackedByteArray_encode_u16(PackedByteArray *p_instance, int64_t p_offset, int64_t p_value) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 2); + uint8_t *w = p_instance->ptrw(); + encode_uint16((uint16_t)p_value, &w[p_offset]); + } + static void func_PackedByteArray_encode_s16(PackedByteArray *p_instance, int64_t p_offset, int64_t p_value) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 2); + uint8_t *w = p_instance->ptrw(); + encode_uint16((int16_t)p_value, &w[p_offset]); + } + + static void func_PackedByteArray_encode_u32(PackedByteArray *p_instance, int64_t p_offset, int64_t p_value) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 4); + uint8_t *w = p_instance->ptrw(); + encode_uint32((uint32_t)p_value, &w[p_offset]); + } + static void func_PackedByteArray_encode_s32(PackedByteArray *p_instance, int64_t p_offset, int64_t p_value) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 4); + uint8_t *w = p_instance->ptrw(); + encode_uint32((int32_t)p_value, &w[p_offset]); + } + + static void func_PackedByteArray_encode_u64(PackedByteArray *p_instance, int64_t p_offset, int64_t p_value) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 8); + uint8_t *w = p_instance->ptrw(); + encode_uint64((uint64_t)p_value, &w[p_offset]); + } + static void func_PackedByteArray_encode_s64(PackedByteArray *p_instance, int64_t p_offset, int64_t p_value) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 8); + uint8_t *w = p_instance->ptrw(); + encode_uint64((int64_t)p_value, &w[p_offset]); + } + + static void func_PackedByteArray_encode_half(PackedByteArray *p_instance, int64_t p_offset, double p_value) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 2); + uint8_t *w = p_instance->ptrw(); + encode_uint16(Math::make_half_float(p_value), &w[p_offset]); + } + static void func_PackedByteArray_encode_float(PackedByteArray *p_instance, int64_t p_offset, double p_value) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 4); + uint8_t *w = p_instance->ptrw(); + encode_float(p_value, &w[p_offset]); + } + static void func_PackedByteArray_encode_double(PackedByteArray *p_instance, int64_t p_offset, double p_value) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 8); + uint8_t *w = p_instance->ptrw(); + encode_double(p_value, &w[p_offset]); + } + static int64_t func_PackedByteArray_encode_var(PackedByteArray *p_instance, int64_t p_offset, const Variant &p_value, bool p_allow_objects) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND_V(p_offset < 0, -1); + uint8_t *w = p_instance->ptrw(); + int len; + Error err = encode_variant(p_value, nullptr, len, p_allow_objects); + if (err != OK) { + return -1; + } + if (uint64_t(p_offset + len) > size) { + return -1; // did not fit + } + encode_variant(p_value, w + p_offset, len, p_allow_objects); + + return len; + } + static void func_Callable_call(Variant *v, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { Callable *callable = VariantGetInternalPtr<Callable>::get_ptr(v); callable->call(p_args, p_argcount, r_ret, r_error); @@ -1005,11 +1230,21 @@ Variant Variant::get_constant_value(Variant::Type p_type, const StringName &p_va #ifdef DEBUG_METHODS_ENABLED #define bind_function(m_type, m_name, m_method, m_arg_names, m_default_args) \ - FUNCTION_CLASS(m_type, m_name, m_method); \ + FUNCTION_CLASS(m_type, m_name, m_method, true); \ register_builtin_method<Method_##m_type##_##m_name>(m_arg_names, m_default_args); #else #define bind_function(m_type, m_name, m_method, m_arg_names, m_default_args) \ - FUNCTION_CLASS(m_type, m_name, m_method); \ + FUNCTION_CLASS(m_type, m_name, m_method, true); \ + register_builtin_method<Method_##m_type##_##m_name>(sarray(), m_default_args); +#endif + +#ifdef DEBUG_METHODS_ENABLED +#define bind_functionnc(m_type, m_name, m_method, m_arg_names, m_default_args) \ + FUNCTION_CLASS(m_type, m_name, m_method, false); \ + register_builtin_method<Method_##m_type##_##m_name>(m_arg_names, m_default_args); +#else +#define bind_functionnc(m_type, m_name, m_method, m_arg_names, m_default_args) \ + FUNCTION_CLASS(m_type, m_name, m_method, false); \ register_builtin_method<Method_##m_type##_##m_name>(sarray(), m_default_args); #endif @@ -1491,6 +1726,34 @@ static void _register_variant_builtin_methods() { bind_function(PackedByteArray, decompress, _VariantCall::func_PackedByteArray_decompress, sarray("buffer_size", "compression_mode"), varray(0)); bind_function(PackedByteArray, decompress_dynamic, _VariantCall::func_PackedByteArray_decompress_dynamic, sarray("max_output_size", "compression_mode"), varray(0)); + bind_function(PackedByteArray, decode_u8, _VariantCall::func_PackedByteArray_decode_u8, sarray("byte_offset"), varray()); + bind_function(PackedByteArray, decode_s8, _VariantCall::func_PackedByteArray_decode_s8, sarray("byte_offset"), varray()); + bind_function(PackedByteArray, decode_u16, _VariantCall::func_PackedByteArray_decode_u16, sarray("byte_offset"), varray()); + bind_function(PackedByteArray, decode_s16, _VariantCall::func_PackedByteArray_decode_s16, sarray("byte_offset"), varray()); + bind_function(PackedByteArray, decode_u32, _VariantCall::func_PackedByteArray_decode_u32, sarray("byte_offset"), varray()); + bind_function(PackedByteArray, decode_s32, _VariantCall::func_PackedByteArray_decode_s32, sarray("byte_offset"), varray()); + bind_function(PackedByteArray, decode_u64, _VariantCall::func_PackedByteArray_decode_u64, sarray("byte_offset"), varray()); + bind_function(PackedByteArray, decode_s64, _VariantCall::func_PackedByteArray_decode_s64, sarray("byte_offset"), varray()); + bind_function(PackedByteArray, decode_half, _VariantCall::func_PackedByteArray_decode_half, sarray("byte_offset"), varray()); + bind_function(PackedByteArray, decode_float, _VariantCall::func_PackedByteArray_decode_float, sarray("byte_offset"), varray()); + bind_function(PackedByteArray, decode_double, _VariantCall::func_PackedByteArray_decode_double, sarray("byte_offset"), varray()); + bind_function(PackedByteArray, has_encoded_var, _VariantCall::func_PackedByteArray_has_encoded_var, sarray("byte_offset", "allow_objects"), varray(false)); + bind_function(PackedByteArray, decode_var, _VariantCall::func_PackedByteArray_decode_var, sarray("byte_offset", "allow_objects"), varray(false)); + bind_function(PackedByteArray, decode_var_size, _VariantCall::func_PackedByteArray_decode_var_size, sarray("byte_offset", "allow_objects"), varray(false)); + + bind_functionnc(PackedByteArray, encode_u8, _VariantCall::func_PackedByteArray_encode_u8, sarray("byte_offset", "value"), varray()); + bind_functionnc(PackedByteArray, encode_s8, _VariantCall::func_PackedByteArray_encode_s8, sarray("byte_offset", "value"), varray()); + bind_functionnc(PackedByteArray, encode_u16, _VariantCall::func_PackedByteArray_encode_u16, sarray("byte_offset", "value"), varray()); + bind_functionnc(PackedByteArray, encode_s16, _VariantCall::func_PackedByteArray_encode_s16, sarray("byte_offset", "value"), varray()); + bind_functionnc(PackedByteArray, encode_u32, _VariantCall::func_PackedByteArray_encode_u32, sarray("byte_offset", "value"), varray()); + bind_functionnc(PackedByteArray, encode_s32, _VariantCall::func_PackedByteArray_encode_s32, sarray("byte_offset", "value"), varray()); + bind_functionnc(PackedByteArray, encode_u64, _VariantCall::func_PackedByteArray_encode_u64, sarray("byte_offset", "value"), varray()); + bind_functionnc(PackedByteArray, encode_s64, _VariantCall::func_PackedByteArray_encode_s64, sarray("byte_offset", "value"), varray()); + bind_functionnc(PackedByteArray, encode_half, _VariantCall::func_PackedByteArray_encode_half, sarray("byte_offset", "value"), varray()); + bind_functionnc(PackedByteArray, encode_float, _VariantCall::func_PackedByteArray_encode_float, sarray("byte_offset", "value"), varray()); + bind_functionnc(PackedByteArray, encode_double, _VariantCall::func_PackedByteArray_encode_double, sarray("byte_offset", "value"), varray()); + bind_functionnc(PackedByteArray, encode_var, _VariantCall::func_PackedByteArray_encode_var, sarray("byte_offset", "value", "allow_objects"), varray(false)); + /* Int32 Array */ bind_method(PackedInt32Array, size, sarray(), varray()); |