Showing the changes to src/vm/list.cpp (1 of 40 files). Show all
Unified · Split
| @@ -0,0 +1,105 @@ | |||
| 1 | // | ||
| 2 | // Dis VM | ||
| 3 | // File: list.cpp | ||
| 4 | // Author: arr | ||
| 5 | // | ||
| 6 | |||
| 7 | #include <runtime.h> | ||
| 8 | #include <vm_memory.h> | ||
| 9 | #include <debug.h> | ||
| 10 | |||
| 11 | using namespace disvm; | ||
| 12 | using namespace disvm::runtime; | ||
| 13 | |||
| 14 | std::shared_ptr<const type_descriptor_t> vm_list_t::type_desc() | ||
| 15 | { | ||
| 16 | return intrinsic_type_desc::type<vm_list_t>(); | ||
| 17 | } | ||
| 18 | |||
| 19 | vm_list_t::vm_list_t(std::shared_ptr<const type_descriptor_t> td, vm_list_t *tail) | ||
| 20 | : vm_alloc_t(vm_list_t::type_desc()) | ||
| 21 | , _element_type{ td } | ||
| 22 | , _is_alloc{ sizeof(_mem) < td->size_in_bytes } | ||
| 23 | , _mem{} | ||
| 24 | , _tail{ tail } | ||
| 25 | { | ||
| 26 | assert(_element_type != nullptr); | ||
| 27 | if (_tail != nullptr) | ||
| 28 | { | ||
| 29 | assert(tail->get_element_type() == _element_type); | ||
| 30 | _tail->add_ref(); | ||
| 31 | } | ||
| 32 | |||
| 33 | // If the default list element storage is not enough, allocate more memory. | ||
| 34 | if (_is_alloc) | ||
| 35 | { | ||
| 36 | _mem.alloc = static_cast<pointer_t>(alloc_memory(_element_type->size_in_bytes)); | ||
| 37 | init_memory(*_element_type, _mem.alloc); | ||
| 38 | } | ||
| 39 | else | ||
| 40 | { | ||
| 41 | init_memory(*_element_type, &_mem.local); | ||
| 42 | } | ||
| 43 | |||
| 44 | debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "init: vm list: new\n"); | ||
| 45 | } | ||
| 46 | |||
| 47 | vm_list_t::~vm_list_t() | ||
| 48 | { | ||
| 49 | // Remove tail | ||
| 50 | dec_ref_count_and_free(_tail); | ||
| 51 | _tail = nullptr; | ||
| 52 | |||
| 53 | // Destroy and free the list element, if default element size was surpassed. | ||
| 54 | if (_is_alloc) | ||
| 55 | { | ||
| 56 | destroy_memory(*_element_type, _mem.alloc); | ||
| 57 | free_memory(_mem.alloc); | ||
| 58 | } | ||
| 59 | else | ||
| 60 | { | ||
| 61 | destroy_memory(*_element_type, &_mem.local); | ||
| 62 | } | ||
| 63 | |||
| 64 | debug::assign_debug_pointer(&_mem.alloc); | ||
| 65 | debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "destroy: vm list\n"); | ||
| 66 | } | ||
| 67 | |||
| 68 | std::shared_ptr<const type_descriptor_t> vm_list_t::get_element_type() const | ||
| 69 | { | ||
| 70 | return _element_type; | ||
| 71 | } | ||
| 72 | |||
| 73 | word_t vm_list_t::get_length() const | ||
| 74 | { | ||
| 75 | auto len = word_t{ 1 }; | ||
| 76 | auto list = _tail; | ||
| 77 | while (list != nullptr) | ||
| 78 | { | ||
| 79 | len++; | ||
| 80 | list = list->get_tail(); | ||
| 81 | } | ||
| 82 | |||
| 83 | return len; | ||
| 84 | } | ||
| 85 | |||
| 86 | vm_list_t *vm_list_t::get_tail() const | ||
| 87 | { | ||
| 88 | return _tail; | ||
| 89 | } | ||
| 90 | |||
| 91 | vm_list_t *vm_list_t::drop_tail() | ||
| 92 | { | ||
| 93 | auto tail = _tail; | ||
| 94 | _tail = nullptr; | ||
| 95 | tail->release(); | ||
| 96 | return tail; | ||
| 97 | } | ||
| 98 | |||
| 99 | pointer_t vm_list_t::value() const | ||
| 100 | { | ||
| 101 | if (_is_alloc) | ||
| 102 | return _mem.alloc; | ||
| 103 | else | ||
| 104 | return reinterpret_cast<pointer_t>(&_mem.local); | ||
| 105 | } | ||