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.cpp | 120 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 71 insertions(+), 49 deletions(-) (limited to 'core/variant.cpp') diff --git a/core/variant.cpp b/core/variant.cpp index 1acb0e7a73..877e188809 100644 --- a/core/variant.cpp +++ b/core/variant.cpp @@ -1005,37 +1005,37 @@ bool Variant::is_zero() const { // arrays case PACKED_BYTE_ARRAY: { - return reinterpret_cast *>(_data._mem)->size() == 0; + return PackedArrayRef::get_array(_data.packed_array).size() == 0; } break; case PACKED_INT_ARRAY: { - return reinterpret_cast *>(_data._mem)->size() == 0; + return PackedArrayRef::get_array(_data.packed_array).size() == 0; } break; case PACKED_REAL_ARRAY: { - return reinterpret_cast *>(_data._mem)->size() == 0; + return PackedArrayRef::get_array(_data.packed_array).size() == 0; } break; case PACKED_STRING_ARRAY: { - return reinterpret_cast *>(_data._mem)->size() == 0; + return PackedArrayRef::get_array(_data.packed_array).size() == 0; } break; case PACKED_VECTOR2_ARRAY: { - return reinterpret_cast *>(_data._mem)->size() == 0; + return PackedArrayRef::get_array(_data.packed_array).size() == 0; } break; case PACKED_VECTOR3_ARRAY: { - return reinterpret_cast *>(_data._mem)->size() == 0; + return PackedArrayRef::get_array(_data.packed_array).size() == 0; } break; case PACKED_COLOR_ARRAY: { - return reinterpret_cast *>(_data._mem)->size() == 0; + return PackedArrayRef::get_array(_data.packed_array).size() == 0; } break; default: { @@ -1275,37 +1275,58 @@ void Variant::reference(const Variant &p_variant) { // arrays case PACKED_BYTE_ARRAY: { - memnew_placement(_data._mem, Vector(*reinterpret_cast *>(p_variant._data._mem))); + _data.packed_array = static_cast *>(p_variant._data.packed_array)->reference(); + if (!_data.packed_array) { + _data.packed_array = PackedArrayRef::create(); + } } break; case PACKED_INT_ARRAY: { - memnew_placement(_data._mem, Vector(*reinterpret_cast *>(p_variant._data._mem))); + _data.packed_array = static_cast *>(p_variant._data.packed_array)->reference(); + if (!_data.packed_array) { + _data.packed_array = PackedArrayRef::create(); + } } break; case PACKED_REAL_ARRAY: { - memnew_placement(_data._mem, Vector(*reinterpret_cast *>(p_variant._data._mem))); + _data.packed_array = static_cast *>(p_variant._data.packed_array)->reference(); + if (!_data.packed_array) { + _data.packed_array = PackedArrayRef::create(); + } } break; case PACKED_STRING_ARRAY: { - memnew_placement(_data._mem, Vector(*reinterpret_cast *>(p_variant._data._mem))); + _data.packed_array = static_cast *>(p_variant._data.packed_array)->reference(); + if (!_data.packed_array) { + _data.packed_array = PackedArrayRef::create(); + } } break; case PACKED_VECTOR2_ARRAY: { - memnew_placement(_data._mem, Vector(*reinterpret_cast *>(p_variant._data._mem))); + _data.packed_array = static_cast *>(p_variant._data.packed_array)->reference(); + if (!_data.packed_array) { + _data.packed_array = PackedArrayRef::create(); + } } break; case PACKED_VECTOR3_ARRAY: { - memnew_placement(_data._mem, Vector(*reinterpret_cast *>(p_variant._data._mem))); + _data.packed_array = static_cast *>(p_variant._data.packed_array)->reference(); + if (!_data.packed_array) { + _data.packed_array = PackedArrayRef::create(); + } } break; case PACKED_COLOR_ARRAY: { - memnew_placement(_data._mem, Vector(*reinterpret_cast *>(p_variant._data._mem))); + _data.packed_array = static_cast *>(p_variant._data.packed_array)->reference(); + if (!_data.packed_array) { + _data.packed_array = PackedArrayRef::create(); + } } break; default: { @@ -1409,31 +1430,31 @@ void Variant::clear() { // arrays case PACKED_BYTE_ARRAY: { - reinterpret_cast *>(_data._mem)->~Vector(); + PackedArrayRefBase::destroy(_data.packed_array); } break; case PACKED_INT_ARRAY: { - reinterpret_cast *>(_data._mem)->~Vector(); + PackedArrayRefBase::destroy(_data.packed_array); } break; case PACKED_REAL_ARRAY: { - reinterpret_cast *>(_data._mem)->~Vector(); + PackedArrayRefBase::destroy(_data.packed_array); } break; case PACKED_STRING_ARRAY: { - reinterpret_cast *>(_data._mem)->~Vector(); + PackedArrayRefBase::destroy(_data.packed_array); } break; case PACKED_VECTOR2_ARRAY: { - reinterpret_cast *>(_data._mem)->~Vector(); + PackedArrayRefBase::destroy(_data.packed_array); } break; case PACKED_VECTOR3_ARRAY: { - reinterpret_cast *>(_data._mem)->~Vector(); + PackedArrayRefBase::destroy(_data.packed_array); } break; case PACKED_COLOR_ARRAY: { - reinterpret_cast *>(_data._mem)->~Vector(); + PackedArrayRefBase::destroy(_data.packed_array); } break; default: { } /* not needed */ @@ -2230,21 +2251,21 @@ Variant::operator Array() const { Variant::operator Vector() const { if (type == PACKED_BYTE_ARRAY) - return *reinterpret_cast *>(_data._mem); + return static_cast *>(_data.packed_array)->array; else return _convert_array_from_variant >(*this); } Variant::operator Vector() const { if (type == PACKED_INT_ARRAY) - return *reinterpret_cast *>(_data._mem); + return static_cast *>(_data.packed_array)->array; else return _convert_array_from_variant >(*this); } Variant::operator Vector() const { if (type == PACKED_REAL_ARRAY) - return *reinterpret_cast *>(_data._mem); + return static_cast *>(_data.packed_array)->array; else return _convert_array_from_variant >(*this); } @@ -2252,21 +2273,21 @@ Variant::operator Vector() const { Variant::operator Vector() const { if (type == PACKED_STRING_ARRAY) - return *reinterpret_cast *>(_data._mem); + return static_cast *>(_data.packed_array)->array; else return _convert_array_from_variant >(*this); } Variant::operator Vector() const { if (type == PACKED_VECTOR3_ARRAY) - return *reinterpret_cast *>(_data._mem); + return static_cast *>(_data.packed_array)->array; else return _convert_array_from_variant >(*this); } Variant::operator Vector() const { if (type == PACKED_VECTOR2_ARRAY) - return *reinterpret_cast *>(_data._mem); + return static_cast *>(_data.packed_array)->array; else return _convert_array_from_variant >(*this); } @@ -2274,7 +2295,7 @@ Variant::operator Vector() const { Variant::operator Vector() const { if (type == PACKED_COLOR_ARRAY) - return *reinterpret_cast *>(_data._mem); + return static_cast *>(_data.packed_array)->array; else return _convert_array_from_variant >(*this); } @@ -2650,38 +2671,39 @@ Variant::Variant(const Vector &p_array) { Variant::Variant(const Vector &p_raw_array) { type = PACKED_BYTE_ARRAY; - memnew_placement(_data._mem, Vector(p_raw_array)); + + _data.packed_array = PackedArrayRef::create(p_raw_array); } Variant::Variant(const Vector &p_int_array) { type = PACKED_INT_ARRAY; - memnew_placement(_data._mem, Vector(p_int_array)); + _data.packed_array = PackedArrayRef::create(p_int_array); } Variant::Variant(const Vector &p_real_array) { type = PACKED_REAL_ARRAY; - memnew_placement(_data._mem, Vector(p_real_array)); + _data.packed_array = PackedArrayRef::create(p_real_array); } Variant::Variant(const Vector &p_string_array) { type = PACKED_STRING_ARRAY; - memnew_placement(_data._mem, Vector(p_string_array)); + _data.packed_array = PackedArrayRef::create(p_string_array); } Variant::Variant(const Vector &p_vector3_array) { type = PACKED_VECTOR3_ARRAY; - memnew_placement(_data._mem, Vector(p_vector3_array)); + _data.packed_array = PackedArrayRef::create(p_vector3_array); } Variant::Variant(const Vector &p_vector2_array) { type = PACKED_VECTOR2_ARRAY; - memnew_placement(_data._mem, Vector(p_vector2_array)); + _data.packed_array = PackedArrayRef::create(p_vector2_array); } Variant::Variant(const Vector &p_color_array) { type = PACKED_COLOR_ARRAY; - memnew_placement(_data._mem, Vector(p_color_array)); + _data.packed_array = PackedArrayRef::create(p_color_array); } Variant::Variant(const Vector &p_face_array) { @@ -2874,31 +2896,31 @@ void Variant::operator=(const Variant &p_variant) { // arrays case PACKED_BYTE_ARRAY: { - *reinterpret_cast *>(_data._mem) = *reinterpret_cast *>(p_variant._data._mem); + _data.packed_array = PackedArrayRef::reference_from(_data.packed_array, p_variant._data.packed_array); } break; case PACKED_INT_ARRAY: { - *reinterpret_cast *>(_data._mem) = *reinterpret_cast *>(p_variant._data._mem); + _data.packed_array = PackedArrayRef::reference_from(_data.packed_array, p_variant._data.packed_array); } break; case PACKED_REAL_ARRAY: { - *reinterpret_cast *>(_data._mem) = *reinterpret_cast *>(p_variant._data._mem); + _data.packed_array = PackedArrayRef::reference_from(_data.packed_array, p_variant._data.packed_array); } break; case PACKED_STRING_ARRAY: { - *reinterpret_cast *>(_data._mem) = *reinterpret_cast *>(p_variant._data._mem); + _data.packed_array = PackedArrayRef::reference_from(_data.packed_array, p_variant._data.packed_array); } break; case PACKED_VECTOR2_ARRAY: { - *reinterpret_cast *>(_data._mem) = *reinterpret_cast *>(p_variant._data._mem); + _data.packed_array = PackedArrayRef::reference_from(_data.packed_array, p_variant._data.packed_array); } break; case PACKED_VECTOR3_ARRAY: { - *reinterpret_cast *>(_data._mem) = *reinterpret_cast *>(p_variant._data._mem); + _data.packed_array = PackedArrayRef::reference_from(_data.packed_array, p_variant._data.packed_array); } break; case PACKED_COLOR_ARRAY: { - *reinterpret_cast *>(_data._mem) = *reinterpret_cast *>(p_variant._data._mem); + _data.packed_array = PackedArrayRef::reference_from(_data.packed_array, p_variant._data.packed_array); } break; default: { } @@ -3106,7 +3128,7 @@ uint32_t Variant::hash() const { } break; case PACKED_BYTE_ARRAY: { - const Vector &arr = *reinterpret_cast *>(_data._mem); + const Vector &arr = PackedArrayRef::get_array(_data.packed_array); int len = arr.size(); if (likely(len)) { const uint8_t *r = arr.ptr(); @@ -3118,7 +3140,7 @@ uint32_t Variant::hash() const { } break; case PACKED_INT_ARRAY: { - const Vector &arr = *reinterpret_cast *>(_data._mem); + const Vector &arr = PackedArrayRef::get_array(_data.packed_array); int len = arr.size(); if (likely(len)) { const int *r = arr.ptr(); @@ -3130,7 +3152,7 @@ uint32_t Variant::hash() const { } break; case PACKED_REAL_ARRAY: { - const Vector &arr = *reinterpret_cast *>(_data._mem); + const Vector &arr = PackedArrayRef::get_array(_data.packed_array); int len = arr.size(); if (likely(len)) { @@ -3144,7 +3166,7 @@ uint32_t Variant::hash() const { case PACKED_STRING_ARRAY: { uint32_t hash = 5831; - const Vector &arr = *reinterpret_cast *>(_data._mem); + const Vector &arr = PackedArrayRef::get_array(_data.packed_array); int len = arr.size(); if (likely(len)) { @@ -3160,7 +3182,7 @@ uint32_t Variant::hash() const { case PACKED_VECTOR2_ARRAY: { uint32_t hash = 5831; - const Vector &arr = *reinterpret_cast *>(_data._mem); + const Vector &arr = PackedArrayRef::get_array(_data.packed_array); int len = arr.size(); if (likely(len)) { @@ -3177,7 +3199,7 @@ uint32_t Variant::hash() const { case PACKED_VECTOR3_ARRAY: { uint32_t hash = 5831; - const Vector &arr = *reinterpret_cast *>(_data._mem); + const Vector &arr = PackedArrayRef::get_array(_data.packed_array); int len = arr.size(); if (likely(len)) { @@ -3195,7 +3217,7 @@ uint32_t Variant::hash() const { case PACKED_COLOR_ARRAY: { uint32_t hash = 5831; - const Vector &arr = *reinterpret_cast *>(_data._mem); + const Vector &arr = PackedArrayRef::get_array(_data.packed_array); int len = arr.size(); if (likely(len)) { -- cgit v1.2.3