From 88f84c78ca14a9dbfdec83692667b46bc4826a7b Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Sun, 23 Feb 2020 18:01:26 -0300 Subject: Store arrays inside of Variant as shared. Arrays inside of Variant are unique and use reference counting. When you assign a variant containing a packed array to another, or when you call non const functions to arrays, this will work even if the array is inside a dictionary, so they will from now pass as reference. The difference with regular variant arrays is that, once passed to a function in the C++ API, they are no longer shared. This is required for security and thread safety, as those arrays are mainly used to pass data back and forth even between threads. --- core/variant_op.cpp | 119 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 73 insertions(+), 46 deletions(-) (limited to 'core/variant_op.cpp') diff --git a/core/variant_op.cpp b/core/variant_op.cpp index 6af4b3887c..37f890e069 100644 --- a/core/variant_op.cpp +++ b/core/variant_op.cpp @@ -392,8 +392,8 @@ bool Variant::booleanize() const { if (p_a.type != p_b.type) \ _RETURN_FAIL \ \ - const Vector &array_a = *reinterpret_cast *>(p_a._data._mem); \ - const Vector &array_b = *reinterpret_cast *>(p_b._data._mem); \ + const Vector &array_a = PackedArrayRef::get_array(p_a._data.packed_array); \ + const Vector &array_b = PackedArrayRef::get_array(p_b._data.packed_array); \ \ int a_len = array_a.size(); \ if (a_len m_opa array_b.size()) { \ @@ -416,8 +416,8 @@ bool Variant::booleanize() const { if (p_a.type != p_b.type) \ _RETURN_FAIL; \ \ - const Vector &array_a = *reinterpret_cast *>(p_a._data._mem); \ - const Vector &array_b = *reinterpret_cast *>(p_b._data._mem); \ + const Vector &array_a = PackedArrayRef::get_array(p_a._data.packed_array); \ + const Vector &array_b = PackedArrayRef::get_array(p_b._data.packed_array); \ Vector sum = array_a; \ sum.append_array(array_b); \ _RETURN(sum); \ @@ -1951,11 +1951,38 @@ Variant Variant::get_named(const StringName &p_index, bool *r_valid) const { } \ } break; -#define DEFAULT_OP_DVECTOR_SET(m_name, dv_type, skip_cond) \ - DEFAULT_OP_ARRAY_CMD(m_name, Vector, if (skip_cond) return;, arr->set(index, p_value); return ) +#define DEFAULT_OP_DVECTOR_SET(m_name, m_type, skip_cond) \ + case m_name: { \ + if (skip_cond) return; \ + \ + if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::REAL) { \ + int index = p_index; \ + Vector *arr = PackedArrayRef::get_array_ptr(_data.packed_array); \ + \ + if (index < 0) \ + index += arr->size(); \ + if (index >= 0 && index < arr->size()) { \ + valid = true; \ + arr->set(index, p_value); \ + } \ + } \ + } break; -#define DEFAULT_OP_DVECTOR_GET(m_name, dv_type) \ - DEFAULT_OP_ARRAY_CMD(m_name, const Vector, ;, return arr->get(index)) +#define DEFAULT_OP_DVECTOR_GET(m_name, m_type) \ + case m_name: { \ + \ + if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::REAL) { \ + int index = p_index; \ + const Vector *arr = &PackedArrayRef::get_array(_data.packed_array); \ + \ + if (index < 0) \ + index += arr->size(); \ + if (index >= 0 && index < arr->size()) { \ + valid = true; \ + return arr->get(index); \ + } \ + } \ + } break; void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid) { @@ -3062,7 +3089,7 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const { if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::REAL) { int index = p_index; - const Vector *arr = reinterpret_cast *>(_data._mem); + const Vector *arr = &PackedArrayRef::get_array(_data.packed_array); int l = arr->size(); if (l) { const uint8_t *r = arr->ptr(); @@ -3080,7 +3107,7 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const { if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::REAL) { int index = p_index; - const Vector *arr = reinterpret_cast *>(_data._mem); + const Vector *arr = &PackedArrayRef::get_array(_data.packed_array); int l = arr->size(); if (l) { const int *r = arr->ptr(); @@ -3098,7 +3125,7 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const { if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::REAL) { real_t index = p_index; - const Vector *arr = reinterpret_cast *>(_data._mem); + const Vector *arr = &PackedArrayRef::get_array(_data.packed_array); int l = arr->size(); if (l) { const real_t *r = arr->ptr(); @@ -3116,7 +3143,7 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const { if (p_index.get_type() == Variant::STRING) { String index = p_index; - const Vector *arr = reinterpret_cast *>(_data._mem); + const Vector *arr = &PackedArrayRef::get_array(_data.packed_array); int l = arr->size(); if (l) { @@ -3135,7 +3162,7 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const { if (p_index.get_type() == Variant::VECTOR2) { Vector2 index = p_index; - const Vector *arr = reinterpret_cast *>(_data._mem); + const Vector *arr = &PackedArrayRef::get_array(_data.packed_array); int l = arr->size(); if (l) { @@ -3154,7 +3181,7 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const { if (p_index.get_type() == Variant::VECTOR3) { Vector3 index = p_index; - const Vector *arr = reinterpret_cast *>(_data._mem); + const Vector *arr = &PackedArrayRef::get_array(_data.packed_array); int l = arr->size(); if (l) { @@ -3174,7 +3201,7 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const { if (p_index.get_type() == Variant::COLOR) { Color index = p_index; - const Vector *arr = reinterpret_cast *>(_data._mem); + const Vector *arr = &PackedArrayRef::get_array(_data.packed_array); int l = arr->size(); if (l) { @@ -3442,7 +3469,7 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const { return true; } break; case PACKED_BYTE_ARRAY: { - const Vector *arr = reinterpret_cast *>(_data._mem); + const Vector *arr = &PackedArrayRef::get_array(_data.packed_array); if (arr->size() == 0) return false; r_iter = 0; @@ -3450,7 +3477,7 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const { } break; case PACKED_INT_ARRAY: { - const Vector *arr = reinterpret_cast *>(_data._mem); + const Vector *arr = &PackedArrayRef::get_array(_data.packed_array); if (arr->size() == 0) return false; r_iter = 0; @@ -3458,7 +3485,7 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const { } break; case PACKED_REAL_ARRAY: { - const Vector *arr = reinterpret_cast *>(_data._mem); + const Vector *arr = &PackedArrayRef::get_array(_data.packed_array); if (arr->size() == 0) return false; r_iter = 0; @@ -3466,7 +3493,7 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const { } break; case PACKED_STRING_ARRAY: { - const Vector *arr = reinterpret_cast *>(_data._mem); + const Vector *arr = &PackedArrayRef::get_array(_data.packed_array); if (arr->size() == 0) return false; r_iter = 0; @@ -3474,7 +3501,7 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const { } break; case PACKED_VECTOR2_ARRAY: { - const Vector *arr = reinterpret_cast *>(_data._mem); + const Vector *arr = &PackedArrayRef::get_array(_data.packed_array); if (arr->size() == 0) return false; r_iter = 0; @@ -3482,7 +3509,7 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const { } break; case PACKED_VECTOR3_ARRAY: { - const Vector *arr = reinterpret_cast *>(_data._mem); + const Vector *arr = &PackedArrayRef::get_array(_data.packed_array); if (arr->size() == 0) return false; r_iter = 0; @@ -3490,7 +3517,7 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const { } break; case PACKED_COLOR_ARRAY: { - const Vector *arr = reinterpret_cast *>(_data._mem); + const Vector *arr = &PackedArrayRef::get_array(_data.packed_array); if (arr->size() == 0) return false; r_iter = 0; @@ -3617,7 +3644,7 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const { return true; } break; case PACKED_BYTE_ARRAY: { - const Vector *arr = reinterpret_cast *>(_data._mem); + const Vector *arr = &PackedArrayRef::get_array(_data.packed_array); int idx = r_iter; idx++; if (idx >= arr->size()) @@ -3627,7 +3654,7 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const { } break; case PACKED_INT_ARRAY: { - const Vector *arr = reinterpret_cast *>(_data._mem); + const Vector *arr = &PackedArrayRef::get_array(_data.packed_array); int idx = r_iter; idx++; if (idx >= arr->size()) @@ -3637,7 +3664,7 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const { } break; case PACKED_REAL_ARRAY: { - const Vector *arr = reinterpret_cast *>(_data._mem); + const Vector *arr = &PackedArrayRef::get_array(_data.packed_array); int idx = r_iter; idx++; if (idx >= arr->size()) @@ -3647,7 +3674,7 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const { } break; case PACKED_STRING_ARRAY: { - const Vector *arr = reinterpret_cast *>(_data._mem); + const Vector *arr = &PackedArrayRef::get_array(_data.packed_array); int idx = r_iter; idx++; if (idx >= arr->size()) @@ -3657,7 +3684,7 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const { } break; case PACKED_VECTOR2_ARRAY: { - const Vector *arr = reinterpret_cast *>(_data._mem); + const Vector *arr = &PackedArrayRef::get_array(_data.packed_array); int idx = r_iter; idx++; if (idx >= arr->size()) @@ -3667,7 +3694,7 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const { } break; case PACKED_VECTOR3_ARRAY: { - const Vector *arr = reinterpret_cast *>(_data._mem); + const Vector *arr = &PackedArrayRef::get_array(_data.packed_array); int idx = r_iter; idx++; if (idx >= arr->size()) @@ -3677,7 +3704,7 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const { } break; case PACKED_COLOR_ARRAY: { - const Vector *arr = reinterpret_cast *>(_data._mem); + const Vector *arr = &PackedArrayRef::get_array(_data.packed_array); int idx = r_iter; idx++; if (idx >= arr->size()) @@ -3764,7 +3791,7 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const { return arr->get(idx); } break; case PACKED_BYTE_ARRAY: { - const Vector *arr = reinterpret_cast *>(_data._mem); + const Vector *arr = &PackedArrayRef::get_array(_data.packed_array); int idx = r_iter; #ifdef DEBUG_ENABLED if (idx < 0 || idx >= arr->size()) { @@ -3775,7 +3802,7 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const { return arr->get(idx); } break; case PACKED_INT_ARRAY: { - const Vector *arr = reinterpret_cast *>(_data._mem); + const Vector *arr = &PackedArrayRef::get_array(_data.packed_array); int idx = r_iter; #ifdef DEBUG_ENABLED if (idx < 0 || idx >= arr->size()) { @@ -3786,7 +3813,7 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const { return arr->get(idx); } break; case PACKED_REAL_ARRAY: { - const Vector *arr = reinterpret_cast *>(_data._mem); + const Vector *arr = &PackedArrayRef::get_array(_data.packed_array); int idx = r_iter; #ifdef DEBUG_ENABLED if (idx < 0 || idx >= arr->size()) { @@ -3797,7 +3824,7 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const { return arr->get(idx); } break; case PACKED_STRING_ARRAY: { - const Vector *arr = reinterpret_cast *>(_data._mem); + const Vector *arr = &PackedArrayRef::get_array(_data.packed_array); int idx = r_iter; #ifdef DEBUG_ENABLED if (idx < 0 || idx >= arr->size()) { @@ -3809,7 +3836,7 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const { } break; case PACKED_VECTOR2_ARRAY: { - const Vector *arr = reinterpret_cast *>(_data._mem); + const Vector *arr = &PackedArrayRef::get_array(_data.packed_array); int idx = r_iter; #ifdef DEBUG_ENABLED if (idx < 0 || idx >= arr->size()) { @@ -3821,7 +3848,7 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const { } break; case PACKED_VECTOR3_ARRAY: { - const Vector *arr = reinterpret_cast *>(_data._mem); + const Vector *arr = &PackedArrayRef::get_array(_data.packed_array); int idx = r_iter; #ifdef DEBUG_ENABLED if (idx < 0 || idx >= arr->size()) { @@ -3833,7 +3860,7 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const { } break; case PACKED_COLOR_ARRAY: { - const Vector *arr = reinterpret_cast *>(_data._mem); + const Vector *arr = &PackedArrayRef::get_array(_data.packed_array); int idx = r_iter; #ifdef DEBUG_ENABLED if (idx < 0 || idx >= arr->size()) { @@ -4167,8 +4194,8 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant & } return; case PACKED_INT_ARRAY: { - const Vector *arr_a = reinterpret_cast *>(a._data._mem); - const Vector *arr_b = reinterpret_cast *>(b._data._mem); + const Vector *arr_a = &PackedArrayRef::get_array(a._data.packed_array); + const Vector *arr_b = &PackedArrayRef::get_array(b._data.packed_array); int sz = arr_a->size(); if (sz == 0 || arr_b->size() != sz) { @@ -4193,8 +4220,8 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant & } return; case PACKED_REAL_ARRAY: { - const Vector *arr_a = reinterpret_cast *>(a._data._mem); - const Vector *arr_b = reinterpret_cast *>(b._data._mem); + const Vector *arr_a = &PackedArrayRef::get_array(a._data.packed_array); + const Vector *arr_b = &PackedArrayRef::get_array(b._data.packed_array); int sz = arr_a->size(); if (sz == 0 || arr_b->size() != sz) { @@ -4223,8 +4250,8 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant & } return; case PACKED_VECTOR2_ARRAY: { - const Vector *arr_a = reinterpret_cast *>(a._data._mem); - const Vector *arr_b = reinterpret_cast *>(b._data._mem); + const Vector *arr_a = &PackedArrayRef::get_array(a._data.packed_array); + const Vector *arr_b = &PackedArrayRef::get_array(b._data.packed_array); int sz = arr_a->size(); if (sz == 0 || arr_b->size() != sz) { @@ -4248,8 +4275,8 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant & return; case PACKED_VECTOR3_ARRAY: { - const Vector *arr_a = reinterpret_cast *>(a._data._mem); - const Vector *arr_b = reinterpret_cast *>(b._data._mem); + const Vector *arr_a = &PackedArrayRef::get_array(a._data.packed_array); + const Vector *arr_b = &PackedArrayRef::get_array(b._data.packed_array); int sz = arr_a->size(); if (sz == 0 || arr_b->size() != sz) { @@ -4272,8 +4299,8 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant & } return; case PACKED_COLOR_ARRAY: { - const Vector *arr_a = reinterpret_cast *>(a._data._mem); - const Vector *arr_b = reinterpret_cast *>(b._data._mem); + const Vector *arr_a = &PackedArrayRef::get_array(a._data.packed_array); + const Vector *arr_b = &PackedArrayRef::get_array(b._data.packed_array); int sz = arr_a->size(); if (sz == 0 || arr_b->size() != sz) { -- cgit v1.2.3