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
11using namespace disvm;
12using namespace disvm::runtime;
13
14std::shared_ptr<const type_descriptor_t> vm_list_t::type_desc()
15{
16 return intrinsic_type_desc::type<vm_list_t>();
17}
18
19vm_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
47vm_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
68std::shared_ptr<const type_descriptor_t> vm_list_t::get_element_type() const
69{
70 return _element_type;
71}
72
73word_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
86vm_list_t *vm_list_t::get_tail() const
87{
88 return _tail;
89}
90
91vm_list_t *vm_list_t::drop_tail()
92{
93 auto tail = _tail;
94 _tail = nullptr;
95 tail->release();
96 return tail;
97}
98
99pointer_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}