Showing the changes to src/vm/array.cpp (1 of 40 files). Show all
Unified · Split
| @@ -0,0 +1,188 @@ | ||
| 1 | +// | |
| 2 | +// Dis VM | |
| 3 | +// File: array.cpp | |
| 4 | +// Author: arr | |
| 5 | +// | |
| 6 | + | |
| 7 | +#include <runtime.h> | |
| 8 | +#include <vm_memory.h> | |
| 9 | +#include <debug.h> | |
| 10 | +#include <exceptions.h> | |
| 11 | + | |
| 12 | +using namespace disvm; | |
| 13 | +using namespace disvm::runtime; | |
| 14 | + | |
| 15 | +std::shared_ptr<const type_descriptor_t> vm_array_t::type_desc() | |
| 16 | +{ | |
| 17 | + return intrinsic_type_desc::type<vm_array_t>(); | |
| 18 | +} | |
| 19 | + | |
| 20 | +vm_array_t::vm_array_t(std::shared_ptr<const type_descriptor_t> td, word_t count) | |
| 21 | + : vm_alloc_t(vm_array_t::type_desc()) | |
| 22 | + , _arr{ nullptr } | |
| 23 | + , _element_type{ td } | |
| 24 | + , _length{ count } | |
| 25 | + , _original{ nullptr } | |
| 26 | +{ | |
| 27 | + assert(_element_type != nullptr); | |
| 28 | + assert(_length >= 0); | |
| 29 | + _arr = alloc_memory<byte_t>(_length * _element_type->size_in_bytes); | |
| 30 | + debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "init: vm array: %d\n", _length); | |
| 31 | + | |
| 32 | + // Initialize the array | |
| 33 | + auto arr_local = _arr; | |
| 34 | + const auto array_len = _length; | |
| 35 | + const auto &element_type = *_element_type; | |
| 36 | + debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "begin: init: elements: %d\n", array_len); | |
| 37 | + for (word_t i = 0; i < array_len; ++i) | |
| 38 | + { | |
| 39 | + init_memory(element_type, arr_local); | |
| 40 | + arr_local += element_type.size_in_bytes; | |
| 41 | + } | |
| 42 | + | |
| 43 | + debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "end: init: elements: %d\n", array_len); | |
| 44 | +} | |
| 45 | + | |
| 46 | +vm_array_t::vm_array_t(std::shared_ptr<const type_descriptor_t> td, word_t count, const zero_memory_t&) | |
| 47 | + : vm_alloc_t(vm_array_t::type_desc()) | |
| 48 | + , _arr{ nullptr } | |
| 49 | + , _element_type{ td } | |
| 50 | + , _length{ count } | |
| 51 | + , _original{ nullptr } | |
| 52 | +{ | |
| 53 | + assert(_element_type != nullptr); | |
| 54 | + assert(_length >= 0); | |
| 55 | + _arr = calloc_memory<byte_t>(_length * _element_type->size_in_bytes); | |
| 56 | + debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "initz: vm array: %d\n", _length); | |
| 57 | +} | |
| 58 | + | |
| 59 | +vm_array_t::vm_array_t(vm_array_t *original, word_t begin_index, word_t count) | |
| 60 | + : vm_alloc_t(vm_array_t::type_desc()) | |
| 61 | + , _arr{ nullptr } | |
| 62 | + , _element_type{ original->get_element_type() } | |
| 63 | + , _length{ count } | |
| 64 | + , _original{ original } | |
| 65 | +{ | |
| 66 | + assert(_original != nullptr); | |
| 67 | + assert(0 <= begin_index && begin_index < _original->get_length()); | |
| 68 | + assert(_length >= 0 && (count - begin_index) < _original->get_length()); | |
| 69 | + | |
| 70 | + if (debug::is_component_tracing_enabled<debug::component_trace_t::memory>()) | |
| 71 | + debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "init: vm array: slice: %d %d\n", begin_index, _length); | |
| 72 | + | |
| 73 | + // Set the data to reference the original array | |
| 74 | + _arr = _original->_arr + (begin_index * _element_type->size_in_bytes); | |
| 75 | + | |
| 76 | + // Check if this is a slice of a slice. | |
| 77 | + if (_original->_original != nullptr) | |
| 78 | + { | |
| 79 | + auto actual_original = _original->_original; | |
| 80 | + dec_ref_count_and_free(_original); | |
| 81 | + | |
| 82 | + _original = actual_original; | |
| 83 | + _original->add_ref(); | |
| 84 | + } | |
| 85 | +} | |
| 86 | + | |
| 87 | +vm_array_t::vm_array_t(const vm_string_t *s) | |
| 88 | + : vm_alloc_t(vm_array_t::type_desc()) | |
| 89 | + , _arr{ nullptr } | |
| 90 | + , _element_type{ intrinsic_type_desc::type<byte_t>() } | |
| 91 | + , _length{ 0 } | |
| 92 | + , _original{ nullptr } | |
| 93 | +{ | |
| 94 | + if (s != nullptr && s->get_length() > 0) | |
| 95 | + { | |
| 96 | + auto str = s->str(); | |
| 97 | + | |
| 98 | + // Ignoring the null terminator. | |
| 99 | + _length = std::strlen(str); | |
| 100 | + _arr = alloc_memory<byte_t>(_length); | |
| 101 | + static_assert(sizeof(byte_t) == sizeof(char), "String characters should be byte size"); | |
| 102 | + | |
| 103 | + std::memcpy(_arr, str, _length); | |
| 104 | + } | |
| 105 | + | |
| 106 | + if (debug::is_component_tracing_enabled<debug::component_trace_t::memory>()) | |
| 107 | + debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "init: vm array: vm string: %d\n", _length); | |
| 108 | +} | |
| 109 | + | |
| 110 | +vm_array_t::~vm_array_t() | |
| 111 | +{ | |
| 112 | + if (_original != nullptr) | |
| 113 | + { | |
| 114 | + // If the array is a sliced (based off of another array) then the | |
| 115 | + // inner pointer simply points into the original array. | |
| 116 | + debug::assign_debug_pointer(&_arr); | |
| 117 | + | |
| 118 | + dec_ref_count_and_free(_original); | |
| 119 | + debug::assign_debug_pointer(&_original); | |
| 120 | + | |
| 121 | + debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "destroy: vm array: slice\n"); | |
| 122 | + } | |
| 123 | + else | |
| 124 | + { | |
| 125 | + // Free the array | |
| 126 | + auto arr_local = _arr; | |
| 127 | + const auto array_len = _length; | |
| 128 | + const auto &element_type = *_element_type; | |
| 129 | + debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "begin: destroy: elements: %d\n", array_len); | |
| 130 | + for (word_t i = 0; i < array_len; ++i) | |
| 131 | + { | |
| 132 | + destroy_memory(element_type, arr_local); | |
| 133 | + arr_local += element_type.size_in_bytes; | |
| 134 | + } | |
| 135 | + debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "end: destroy: elements: %d\n", array_len); | |
| 136 | + | |
| 137 | + // Free array memory | |
| 138 | + free_memory(_arr); | |
| 139 | + | |
| 140 | + debug::assign_debug_pointer(&_arr); | |
| 141 | + debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "destroy: vm array\n"); | |
| 142 | + } | |
| 143 | + | |
| 144 | +} | |
| 145 | + | |
| 146 | +std::shared_ptr<const type_descriptor_t> vm_array_t::get_element_type() const | |
| 147 | +{ | |
| 148 | + return _element_type; | |
| 149 | +} | |
| 150 | + | |
| 151 | +word_t vm_array_t::get_length() const | |
| 152 | +{ | |
| 153 | + return _length; | |
| 154 | +} | |
| 155 | + | |
| 156 | +pointer_t vm_array_t::at(word_t index) const | |
| 157 | +{ | |
| 158 | + if (index < 0 || _length <= index) | |
| 159 | + throw out_of_range_memory{ 0, _length - 1, index }; | |
| 160 | + | |
| 161 | + return reinterpret_cast<pointer_t>(_arr + (index * _element_type->size_in_bytes)); | |
| 162 | +} | |
| 163 | + | |
| 164 | +void vm_array_t::copy_from(const vm_array_t &source, word_t this_begin_index) | |
| 165 | +{ | |
| 166 | + if (this_begin_index < 0 || _length < (this_begin_index + source._length)) | |
| 167 | + throw out_of_range_memory{}; | |
| 168 | + | |
| 169 | + if (source._element_type != _element_type) | |
| 170 | + throw type_violation{}; | |
| 171 | + | |
| 172 | + auto dest_arr = _arr + (this_begin_index * _element_type->size_in_bytes); | |
| 173 | + | |
| 174 | + // Increment all pointers if we have reference types. | |
| 175 | + if (_element_type->map_in_bytes != 0) | |
| 176 | + { | |
| 177 | + assert(false && "Not implemented"); | |
| 178 | + //auto &type_desc = *_element_type; | |
| 179 | + //auto source_array_element = source->_arr; | |
| 180 | + //for (word_t i = 0; i < source->_length; ++i) | |
| 181 | + //{ | |
| 182 | + // source_array_element += (i * type_desc.size_in_bytes); | |
| 183 | + // inc_ref_count_in_alloc(type_desc, source_array_element); | |
| 184 | + //} | |
| 185 | + } | |
| 186 | + | |
| 187 | + std::memcpy(dest_arr, source._arr, (source._length * _element_type->size_in_bytes)); | |
| 188 | +} | |