Unified · Split
| @@ -69,6 +69,8 @@ namespace disvm · 68 unmodified lines | |||
| 69 | type_descriptor_t(const type_descriptor_t&) = delete; | 69 | type_descriptor_t(const type_descriptor_t&) = delete; |
| 70 | type_descriptor_t& operator=(const type_descriptor_t&) = delete; | 70 | type_descriptor_t& operator=(const type_descriptor_t&) = delete; |
| 71 | 71 | ||
| 72 | bool is_equal(const type_descriptor_t *) const; | ||
| 73 | |||
| 72 | const word_t size_in_bytes; | 74 | const word_t size_in_bytes; |
| 73 | const word_t map_in_bytes; | 75 | const word_t map_in_bytes; |
| 74 | const byte_t * const pointer_map; | 76 | const byte_t * const pointer_map; |
| @@ -166,7 +166,7 @@ void vm_array_t::copy_from(const vm_array_t &source, word_t this_begin_index) · 165 unmodified lines | |||
| 166 | if (this_begin_index < 0 || _length < (this_begin_index + source._length)) | 166 | if (this_begin_index < 0 || _length < (this_begin_index + source._length)) |
| 167 | throw out_of_range_memory{}; | 167 | throw out_of_range_memory{}; |
| 168 | 168 | ||
| 169 | if (source._element_type != _element_type) | 169 | if (!source._element_type->is_equal(_element_type.get())) |
| 170 | throw type_violation{}; | 170 | throw type_violation{}; |
| 171 | 171 | ||
| 172 | auto dest_arr = _arr + (this_begin_index * _element_type->size_in_bytes); | 172 | auto dest_arr = _arr + (this_begin_index * _element_type->size_in_bytes); |
| @@ -174,15 +174,15 @@ void vm_array_t::copy_from(const vm_array_t &source, word_t this_begin_index) · 1 unmodified line | |||
| 174 | // Increment all pointers if we have reference types. | 174 | // Increment all pointers if we have reference types. |
| 175 | if (_element_type->map_in_bytes != 0) | 175 | if (_element_type->map_in_bytes != 0) |
| 176 | { | 176 | { |
| 177 | assert(false && "Not implemented"); | 177 | auto &type_desc = *_element_type; |
| 178 | //auto &type_desc = *_element_type; | 178 | auto source_array_element = source._arr; |
| 179 | //auto source_array_element = source->_arr; | 179 | for (auto i = word_t{ 0 }; i < source._length; ++i) |
| 180 | //for (word_t i = 0; i < source->_length; ++i) | 180 | { |
| 181 | //{ | 181 | source_array_element += (i * type_desc.size_in_bytes); |
| 182 | // source_array_element += (i * type_desc.size_in_bytes); | 182 | inc_ref_count_in_memory(type_desc, source_array_element); |
| 183 | // inc_ref_count_in_alloc(type_desc, source_array_element); | 183 | } |
| 184 | //} | ||
| 185 | } | 184 | } |
| 186 | 185 | ||
| 187 | std::memcpy(dest_arr, source._arr, (source._length * _element_type->size_in_bytes)); | 186 | // Moving data within the same array is permitted so use memmove(). |
| 187 | std::memmove(dest_arr, source._arr, (source._length * _element_type->size_in_bytes)); | ||
| 188 | } | 188 | } |
| @@ -1403,7 +1403,7 @@ namespace · 1402 unmodified lines | |||
| 1403 | if (s == nullptr) | 1403 | if (s == nullptr) |
| 1404 | return; | 1404 | return; |
| 1405 | 1405 | ||
| 1406 | if (d == nullptr || s->alloc_type != d->alloc_type) | 1406 | if (d == nullptr || !s->alloc_type->is_equal(d->alloc_type.get())) |
| 1407 | throw type_violation{}; | 1407 | throw type_violation{}; |
| 1408 | } | 1408 | } |
| 1409 | 1409 | ||
| @@ -90,7 +90,7 @@ void vm_list_t::set_tail(vm_list_t *new_tail) · 89 unmodified lines | |||
| 90 | { | 90 | { |
| 91 | if (new_tail != nullptr) | 91 | if (new_tail != nullptr) |
| 92 | { | 92 | { |
| 93 | if (new_tail->get_element_type() != _element_type) | 93 | if (!new_tail->get_element_type()->is_equal(_element_type.get())) |
| 94 | throw type_violation{}; | 94 | throw type_violation{}; |
| 95 | 95 | ||
| 96 | new_tail->add_ref(); | 96 | new_tail->add_ref(); |
| @@ -530,3 +530,19 @@ type_descriptor_t::type_descriptor_t( · 529 unmodified lines | |||
| 530 | if (debug::is_component_tracing_enabled<debug::component_trace_t::memory>()) | 530 | if (debug::is_component_tracing_enabled<debug::component_trace_t::memory>()) |
| 531 | debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "init: type descriptor"); | 531 | debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "init: type descriptor"); |
| 532 | } | 532 | } |
| 533 | |||
| 534 | bool type_descriptor_t::is_equal(const type_descriptor_t *other) const | ||
| 535 | { | ||
| 536 | if (other == nullptr) | ||
| 537 | return false; | ||
| 538 | |||
| 539 | if (this == other) | ||
| 540 | return true; | ||
| 541 | |||
| 542 | bool equal = size_in_bytes == other->size_in_bytes; | ||
| 543 | equal = equal && map_in_bytes == other->map_in_bytes; | ||
| 544 | equal = equal && 0 == std::memcmp(pointer_map, other->pointer_map, map_in_bytes); | ||
| 545 | equal = equal && finalizer == other->finalizer; | ||
| 546 | |||
| 547 | return equal; | ||
| 548 | } | ||