History

Initial public commit for Dis VM

arr committed 10 years ago

Commit f95902eNo parent (first commit)40 files · +9358 −0Browse files

Showing the changes to src/vm/list.cpp (1 of 40 files). Show all

Unified · Split

src/vm/list.cpp+105−0
@@ -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+}