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/array.cpp (1 of 40 files). Show all

Unified · Split

src/vm/array.cpp+188−0
@@ -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
12using namespace disvm;
13using namespace disvm::runtime;
14
15std::shared_ptr<const type_descriptor_t> vm_array_t::type_desc()
16{
17 return intrinsic_type_desc::type<vm_array_t>();
18}
19
20vm_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
46vm_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
59vm_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
87vm_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
110vm_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
146std::shared_ptr<const type_descriptor_t> vm_array_t::get_element_type() const
147{
148 return _element_type;
149}
150
151word_t vm_array_t::get_length() const
152{
153 return _length;
154}
155
156pointer_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
164void 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}